Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/ioctl_linux.c
1307 views
1
/******************************************************************************
2
*
3
* Copyright(c) 2007 - 2017 Realtek Corporation.
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms of version 2 of the GNU General Public License as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
*****************************************************************************/
15
#define _IOCTL_LINUX_C_
16
17
#include <drv_types.h>
18
#include <rtw_mp.h>
19
#include "../../hal/phydm/phydm_precomp.h"
20
#ifdef RTW_HALMAC
21
#include "../../hal/hal_halmac.h"
22
#endif
23
24
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27))
25
#define iwe_stream_add_event(a, b, c, d, e) iwe_stream_add_event(b, c, d, e)
26
#define iwe_stream_add_point(a, b, c, d, e) iwe_stream_add_point(b, c, d, e)
27
#endif
28
29
#ifdef CONFIG_80211N_HT
30
extern int rtw_ht_enable;
31
#endif
32
33
34
#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV+30)
35
36
#define SCAN_ITEM_SIZE 768
37
#define MAX_CUSTOM_LEN 64
38
#define RATE_COUNT 4
39
#define MAX_SCAN_BUFFER_LEN 65535
40
41
#ifdef CONFIG_GLOBAL_UI_PID
42
extern int ui_pid[3];
43
#endif
44
45
/* combo scan */
46
#define WEXT_CSCAN_AMOUNT 9
47
#define WEXT_CSCAN_BUF_LEN 360
48
#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
49
#define WEXT_CSCAN_HEADER_SIZE 12
50
#define WEXT_CSCAN_SSID_SECTION 'S'
51
#define WEXT_CSCAN_CHANNEL_SECTION 'C'
52
#define WEXT_CSCAN_NPROBE_SECTION 'N'
53
#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
54
#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
55
#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
56
#define WEXT_CSCAN_TYPE_SECTION 'T'
57
58
59
extern u8 key_2char2num(u8 hch, u8 lch);
60
extern u8 str_2char2num(u8 hch, u8 lch);
61
extern void macstr2num(u8 *dst, u8 *src);
62
extern u8 convert_ip_addr(u8 hch, u8 mch, u8 lch);
63
64
u32 rtw_rates[] = {1000000, 2000000, 5500000, 11000000,
65
6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
66
67
/**
68
* hwaddr_aton - Convert ASCII string to MAC address
69
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
70
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
71
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
72
*/
73
static int hwaddr_aton_i(const char *txt, u8 *addr)
74
{
75
int i;
76
77
for (i = 0; i < 6; i++) {
78
int a, b;
79
80
a = hex2num_i(*txt++);
81
if (a < 0)
82
return -1;
83
b = hex2num_i(*txt++);
84
if (b < 0)
85
return -1;
86
*addr++ = (a << 4) | b;
87
if (i < 5 && *txt++ != ':')
88
return -1;
89
}
90
91
return 0;
92
}
93
#ifdef CONFIG_ANDROID
94
static void indicate_wx_custom_event(_adapter *padapter, char *msg)
95
{
96
u8 *buff;
97
union iwreq_data wrqu;
98
99
if (strlen(msg) > IW_CUSTOM_MAX) {
100
RTW_INFO("%s strlen(msg):%zu > IW_CUSTOM_MAX:%u\n", __FUNCTION__ , strlen(msg), IW_CUSTOM_MAX);
101
return;
102
}
103
104
buff = rtw_zmalloc(IW_CUSTOM_MAX + 1);
105
if (!buff)
106
return;
107
108
_rtw_memcpy(buff, msg, strlen(msg));
109
110
_rtw_memset(&wrqu, 0, sizeof(wrqu));
111
wrqu.data.length = strlen(msg);
112
113
RTW_INFO("%s %s\n", __FUNCTION__, buff);
114
#ifndef CONFIG_IOCTL_CFG80211
115
wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
116
#endif
117
118
rtw_mfree(buff, IW_CUSTOM_MAX + 1);
119
120
}
121
#endif
122
123
#if 0
124
static void request_wps_pbc_event(_adapter *padapter)
125
{
126
u8 *buff, *p;
127
union iwreq_data wrqu;
128
129
130
buff = rtw_malloc(IW_CUSTOM_MAX);
131
if (!buff)
132
return;
133
134
_rtw_memset(buff, 0, IW_CUSTOM_MAX);
135
136
p = buff;
137
138
p += sprintf(p, "WPS_PBC_START.request=TRUE");
139
140
_rtw_memset(&wrqu, 0, sizeof(wrqu));
141
142
wrqu.data.length = p - buff;
143
144
wrqu.data.length = (wrqu.data.length < IW_CUSTOM_MAX) ? wrqu.data.length : IW_CUSTOM_MAX;
145
146
RTW_INFO("%s\n", __FUNCTION__);
147
148
#ifndef CONFIG_IOCTL_CFG80211
149
wireless_send_event(padapter->pnetdev, IWEVCUSTOM, &wrqu, buff);
150
#endif
151
152
if (buff)
153
rtw_mfree(buff, IW_CUSTOM_MAX);
154
155
}
156
#endif
157
158
#ifdef CONFIG_SUPPORT_HW_WPS_PBC
159
void rtw_request_wps_pbc_event(_adapter *padapter)
160
{
161
#ifdef RTK_DMP_PLATFORM
162
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 12))
163
kobject_uevent(&padapter->pnetdev->dev.kobj, KOBJ_NET_PBC);
164
#else
165
kobject_hotplug(&padapter->pnetdev->class_dev.kobj, KOBJ_NET_PBC);
166
#endif
167
#else
168
169
if (padapter->pid[0] == 0) {
170
/* 0 is the default value and it means the application monitors the HW PBC doesn't privde its pid to driver. */
171
return;
172
}
173
174
rtw_signal_process(padapter->pid[0], SIGUSR1);
175
176
#endif
177
178
rtw_led_control(padapter, LED_CTL_START_WPS_BOTTON);
179
}
180
#endif/* #ifdef CONFIG_SUPPORT_HW_WPS_PBC */
181
182
void indicate_wx_scan_complete_event(_adapter *padapter)
183
{
184
union iwreq_data wrqu;
185
186
_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
187
188
/* RTW_INFO("+rtw_indicate_wx_scan_complete_event\n"); */
189
#ifndef CONFIG_IOCTL_CFG80211
190
wireless_send_event(padapter->pnetdev, SIOCGIWSCAN, &wrqu, NULL);
191
#endif
192
}
193
194
195
void rtw_indicate_wx_assoc_event(_adapter *padapter)
196
{
197
union iwreq_data wrqu;
198
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
199
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
200
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
201
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
202
203
_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
204
205
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
206
207
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)
208
_rtw_memcpy(wrqu.ap_addr.sa_data, pnetwork->MacAddress, ETH_ALEN);
209
else
210
_rtw_memcpy(wrqu.ap_addr.sa_data, pmlmepriv->cur_network.network.MacAddress, ETH_ALEN);
211
212
RTW_PRINT("assoc success\n");
213
#ifndef CONFIG_IOCTL_CFG80211
214
wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
215
#endif
216
}
217
218
void rtw_indicate_wx_disassoc_event(_adapter *padapter)
219
{
220
union iwreq_data wrqu;
221
222
_rtw_memset(&wrqu, 0, sizeof(union iwreq_data));
223
224
wrqu.ap_addr.sa_family = ARPHRD_ETHER;
225
_rtw_memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
226
227
#ifndef CONFIG_IOCTL_CFG80211
228
RTW_PRINT("indicate disassoc\n");
229
wireless_send_event(padapter->pnetdev, SIOCGIWAP, &wrqu, NULL);
230
#endif
231
}
232
233
/*
234
uint rtw_is_cckrates_included(u8 *rate)
235
{
236
u32 i = 0;
237
238
while(rate[i]!=0)
239
{
240
if ( (((rate[i]) & 0x7f) == 2) || (((rate[i]) & 0x7f) == 4) ||
241
(((rate[i]) & 0x7f) == 11) || (((rate[i]) & 0x7f) == 22) )
242
return _TRUE;
243
i++;
244
}
245
246
return _FALSE;
247
}
248
249
uint rtw_is_cckratesonly_included(u8 *rate)
250
{
251
u32 i = 0;
252
253
while(rate[i]!=0)
254
{
255
if ( (((rate[i]) & 0x7f) != 2) && (((rate[i]) & 0x7f) != 4) &&
256
(((rate[i]) & 0x7f) != 11) && (((rate[i]) & 0x7f) != 22) )
257
return _FALSE;
258
i++;
259
}
260
261
return _TRUE;
262
}
263
*/
264
265
static int search_p2p_wfd_ie(_adapter *padapter,
266
struct iw_request_info *info, struct wlan_network *pnetwork,
267
char *start, char *stop)
268
{
269
#ifdef CONFIG_P2P
270
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
271
#ifdef CONFIG_WFD
272
if (SCAN_RESULT_ALL == pwdinfo->wfd_info->scan_result_type) {
273
274
} else if ((SCAN_RESULT_P2P_ONLY == pwdinfo->wfd_info->scan_result_type) ||
275
(SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type))
276
#endif /* CONFIG_WFD */
277
{
278
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
279
u32 blnGotP2PIE = _FALSE;
280
281
/* User is doing the P2P device discovery */
282
/* The prefix of SSID should be "DIRECT-" and the IE should contains the P2P IE. */
283
/* If not, the driver should ignore this AP and go to the next AP. */
284
285
/* Verifying the SSID */
286
if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN)) {
287
u32 p2pielen = 0;
288
289
/* Verifying the P2P IE */
290
if (rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen))
291
blnGotP2PIE = _TRUE;
292
}
293
294
if (blnGotP2PIE == _FALSE)
295
return _FALSE;
296
297
}
298
}
299
300
#ifdef CONFIG_WFD
301
if (SCAN_RESULT_WFD_TYPE == pwdinfo->wfd_info->scan_result_type) {
302
u32 blnGotWFD = _FALSE;
303
u8 *wfd_ie;
304
uint wfd_ielen = 0;
305
306
wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
307
if (wfd_ie) {
308
u8 *wfd_devinfo;
309
uint wfd_devlen;
310
311
wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
312
if (wfd_devinfo) {
313
if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_PSINK) {
314
/* the first two bits will indicate the WFD device type */
315
if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_SOURCE) {
316
/* If this device is Miracast PSink device, the scan reuslt should just provide the Miracast source. */
317
blnGotWFD = _TRUE;
318
}
319
} else if (pwdinfo->wfd_info->wfd_device_type == WFD_DEVINFO_SOURCE) {
320
/* the first two bits will indicate the WFD device type */
321
if ((wfd_devinfo[1] & 0x03) == WFD_DEVINFO_PSINK) {
322
/* If this device is Miracast source device, the scan reuslt should just provide the Miracast PSink. */
323
/* Todo: How about the SSink?! */
324
blnGotWFD = _TRUE;
325
}
326
}
327
}
328
}
329
330
if (blnGotWFD == _FALSE)
331
return _FALSE;
332
}
333
#endif /* CONFIG_WFD */
334
335
#endif /* CONFIG_P2P */
336
return _TRUE;
337
}
338
static inline char *iwe_stream_mac_addr_proess(_adapter *padapter,
339
struct iw_request_info *info, struct wlan_network *pnetwork,
340
char *start, char *stop, struct iw_event *iwe)
341
{
342
/* AP MAC address */
343
iwe->cmd = SIOCGIWAP;
344
iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
345
346
_rtw_memcpy(iwe->u.ap_addr.sa_data, pnetwork->network.MacAddress, ETH_ALEN);
347
start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_ADDR_LEN);
348
return start;
349
}
350
static inline char *iwe_stream_essid_proess(_adapter *padapter,
351
struct iw_request_info *info, struct wlan_network *pnetwork,
352
char *start, char *stop, struct iw_event *iwe)
353
{
354
355
/* Add the ESSID */
356
iwe->cmd = SIOCGIWESSID;
357
iwe->u.data.flags = 1;
358
iwe->u.data.length = min((u16)pnetwork->network.Ssid.SsidLength, (u16)32);
359
start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
360
return start;
361
}
362
363
static inline char *iwe_stream_chan_process(_adapter *padapter,
364
struct iw_request_info *info, struct wlan_network *pnetwork,
365
char *start, char *stop, struct iw_event *iwe)
366
{
367
if (pnetwork->network.Configuration.DSConfig < 1 /*|| pnetwork->network.Configuration.DSConfig>14*/)
368
pnetwork->network.Configuration.DSConfig = 1;
369
370
/* Add frequency/channel */
371
iwe->cmd = SIOCGIWFREQ;
372
iwe->u.freq.m = rtw_ch2freq(pnetwork->network.Configuration.DSConfig) * 100000;
373
iwe->u.freq.e = 1;
374
iwe->u.freq.i = pnetwork->network.Configuration.DSConfig;
375
start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_FREQ_LEN);
376
return start;
377
}
378
static inline char *iwe_stream_mode_process(_adapter *padapter,
379
struct iw_request_info *info, struct wlan_network *pnetwork,
380
char *start, char *stop, struct iw_event *iwe, u16 cap)
381
{
382
/* Add mode */
383
if (cap & (WLAN_CAPABILITY_IBSS | WLAN_CAPABILITY_BSS)) {
384
iwe->cmd = SIOCGIWMODE;
385
if (cap & WLAN_CAPABILITY_BSS)
386
iwe->u.mode = IW_MODE_MASTER;
387
else
388
iwe->u.mode = IW_MODE_ADHOC;
389
390
start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_UINT_LEN);
391
}
392
return start;
393
}
394
static inline char *iwe_stream_encryption_process(_adapter *padapter,
395
struct iw_request_info *info, struct wlan_network *pnetwork,
396
char *start, char *stop, struct iw_event *iwe, u16 cap)
397
{
398
399
/* Add encryption capability */
400
iwe->cmd = SIOCGIWENCODE;
401
if (cap & WLAN_CAPABILITY_PRIVACY)
402
iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
403
else
404
iwe->u.data.flags = IW_ENCODE_DISABLED;
405
iwe->u.data.length = 0;
406
start = iwe_stream_add_point(info, start, stop, iwe, pnetwork->network.Ssid.Ssid);
407
return start;
408
409
}
410
411
static inline char *iwe_stream_protocol_process(_adapter *padapter,
412
struct iw_request_info *info, struct wlan_network *pnetwork,
413
char *start, char *stop, struct iw_event *iwe)
414
{
415
u16 ht_cap = _FALSE, vht_cap = _FALSE;
416
u32 ht_ielen = 0, vht_ielen = 0;
417
char *p;
418
u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request */
419
420
#ifdef CONFIG_80211N_HT
421
/* parsing HT_CAP_IE */
422
if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode)) {
423
p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
424
if (p && ht_ielen > 0)
425
ht_cap = _TRUE;
426
}
427
#endif
428
429
#ifdef CONFIG_80211AC_VHT
430
/* parsing VHT_CAP_IE */
431
if(padapter->registrypriv.wireless_mode & WIRELESS_11AC) {
432
p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
433
if (p && vht_ielen > 0)
434
vht_cap = _TRUE;
435
}
436
#endif
437
/* Add the protocol name */
438
iwe->cmd = SIOCGIWNAME;
439
if ((rtw_is_cckratesonly_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
440
if (ht_cap == _TRUE)
441
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bn");
442
else
443
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11b");
444
} else if ((rtw_is_cckrates_included((u8 *)&pnetwork->network.SupportedRates)) == _TRUE) {
445
if (ht_cap == _TRUE)
446
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bgn");
447
else
448
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11bg");
449
} else {
450
if (pnetwork->network.Configuration.DSConfig > 14) {
451
#ifdef CONFIG_80211AC_VHT
452
if (vht_cap == _TRUE)
453
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11AC");
454
else
455
#endif
456
{
457
if (ht_cap == _TRUE)
458
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11an");
459
else
460
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11a");
461
}
462
} else {
463
if (ht_cap == _TRUE)
464
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11gn");
465
else
466
snprintf(iwe->u.name, IFNAMSIZ, "IEEE 802.11g");
467
}
468
}
469
start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_CHAR_LEN);
470
return start;
471
}
472
473
static inline char *iwe_stream_rate_process(_adapter *padapter,
474
struct iw_request_info *info, struct wlan_network *pnetwork,
475
char *start, char *stop, struct iw_event *iwe)
476
{
477
u32 ht_ielen = 0, vht_ielen = 0;
478
char *p;
479
u16 max_rate = 0, rate, ht_cap = _FALSE, vht_cap = _FALSE;
480
u32 i = 0;
481
u8 bw_40MHz = 0, short_GI = 0, bw_160MHz = 0, vht_highest_rate = 0;
482
u16 mcs_rate = 0, vht_data_rate = 0;
483
char custom[MAX_CUSTOM_LEN] = {0};
484
u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12); /* Probe Request */
485
486
/* parsing HT_CAP_IE */
487
if(is_supported_ht(padapter->registrypriv.wireless_mode)) {
488
p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], _HT_CAPABILITY_IE_, &ht_ielen, pnetwork->network.IELength - ie_offset);
489
if (p && ht_ielen > 0) {
490
struct rtw_ieee80211_ht_cap *pht_capie;
491
ht_cap = _TRUE;
492
pht_capie = (struct rtw_ieee80211_ht_cap *)(p + 2);
493
_rtw_memcpy(&mcs_rate , pht_capie->supp_mcs_set, 2);
494
bw_40MHz = (pht_capie->cap_info & IEEE80211_HT_CAP_SUP_WIDTH) ? 1 : 0;
495
short_GI = (pht_capie->cap_info & (IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40)) ? 1 : 0;
496
}
497
}
498
#ifdef CONFIG_80211AC_VHT
499
/* parsing VHT_CAP_IE */
500
if(padapter->registrypriv.wireless_mode & WIRELESS_11AC){
501
p = rtw_get_ie(&pnetwork->network.IEs[ie_offset], EID_VHTCapability, &vht_ielen, pnetwork->network.IELength - ie_offset);
502
if (p && vht_ielen > 0) {
503
u8 mcs_map[2];
504
505
vht_cap = _TRUE;
506
bw_160MHz = GET_VHT_CAPABILITY_ELE_CHL_WIDTH(p + 2);
507
if (bw_160MHz)
508
short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI160M(p + 2);
509
else
510
short_GI = GET_VHT_CAPABILITY_ELE_SHORT_GI80M(p + 2);
511
512
_rtw_memcpy(mcs_map, GET_VHT_CAPABILITY_ELE_TX_MCS(p + 2), 2);
513
514
vht_highest_rate = rtw_get_vht_highest_rate(mcs_map);
515
vht_data_rate = rtw_vht_mcs_to_data_rate(CHANNEL_WIDTH_80, short_GI, vht_highest_rate);
516
}
517
}
518
#endif
519
520
/*Add basic and extended rates */
521
p = custom;
522
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
523
while (pnetwork->network.SupportedRates[i] != 0) {
524
rate = pnetwork->network.SupportedRates[i] & 0x7F;
525
if (rate > max_rate)
526
max_rate = rate;
527
p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
528
"%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
529
i++;
530
}
531
#ifdef CONFIG_80211AC_VHT
532
if (vht_cap == _TRUE)
533
max_rate = vht_data_rate;
534
else
535
#endif
536
if (ht_cap == _TRUE) {
537
if (mcs_rate & 0x8000) /* MCS15 */
538
max_rate = (bw_40MHz) ? ((short_GI) ? 300 : 270) : ((short_GI) ? 144 : 130);
539
540
else if (mcs_rate & 0x0080) /* MCS7 */
541
max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
542
else { /* default MCS7 */
543
/* RTW_INFO("wx_get_scan, mcs_rate_bitmap=0x%x\n", mcs_rate); */
544
max_rate = (bw_40MHz) ? ((short_GI) ? 150 : 135) : ((short_GI) ? 72 : 65);
545
}
546
547
max_rate = max_rate * 2; /* Mbps/2; */
548
}
549
550
iwe->cmd = SIOCGIWRATE;
551
iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
552
iwe->u.bitrate.value = max_rate * 500000;
553
start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_PARAM_LEN);
554
return start ;
555
}
556
557
static inline char *iwe_stream_wpa_wpa2_process(_adapter *padapter,
558
struct iw_request_info *info, struct wlan_network *pnetwork,
559
char *start, char *stop, struct iw_event *iwe)
560
{
561
int buf_size = MAX_WPA_IE_LEN * 2;
562
/* u8 pbuf[buf_size]={0}; */
563
u8 *pbuf = rtw_zmalloc(buf_size);
564
565
u8 wpa_ie[255] = {0}, rsn_ie[255] = {0};
566
u16 i, wpa_len = 0, rsn_len = 0;
567
u8 *p;
568
sint out_len = 0;
569
570
571
if (pbuf) {
572
p = pbuf;
573
574
/* parsing WPA/WPA2 IE */
575
if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */
576
out_len = rtw_get_sec_ie(pnetwork->network.IEs , pnetwork->network.IELength, rsn_ie, &rsn_len, wpa_ie, &wpa_len);
577
578
if (wpa_len > 0) {
579
580
_rtw_memset(pbuf, 0, buf_size);
581
p += sprintf(p, "wpa_ie=");
582
for (i = 0; i < wpa_len; i++)
583
p += sprintf(p, "%02x", wpa_ie[i]);
584
585
if (wpa_len > 100) {
586
printk("-----------------Len %d----------------\n", wpa_len);
587
for (i = 0; i < wpa_len; i++)
588
printk("%02x ", wpa_ie[i]);
589
printk("\n");
590
printk("-----------------Len %d----------------\n", wpa_len);
591
}
592
593
_rtw_memset(iwe, 0, sizeof(*iwe));
594
iwe->cmd = IWEVCUSTOM;
595
iwe->u.data.length = strlen(pbuf);
596
start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
597
598
_rtw_memset(iwe, 0, sizeof(*iwe));
599
iwe->cmd = IWEVGENIE;
600
iwe->u.data.length = wpa_len;
601
start = iwe_stream_add_point(info, start, stop, iwe, wpa_ie);
602
}
603
if (rsn_len > 0) {
604
605
_rtw_memset(pbuf, 0, buf_size);
606
p += sprintf(p, "rsn_ie=");
607
for (i = 0; i < rsn_len; i++)
608
p += sprintf(p, "%02x", rsn_ie[i]);
609
_rtw_memset(iwe, 0, sizeof(*iwe));
610
iwe->cmd = IWEVCUSTOM;
611
iwe->u.data.length = strlen(pbuf);
612
start = iwe_stream_add_point(info, start, stop, iwe, pbuf);
613
614
_rtw_memset(iwe, 0, sizeof(*iwe));
615
iwe->cmd = IWEVGENIE;
616
iwe->u.data.length = rsn_len;
617
start = iwe_stream_add_point(info, start, stop, iwe, rsn_ie);
618
}
619
}
620
621
rtw_mfree(pbuf, buf_size);
622
}
623
return start;
624
}
625
626
static inline char *iwe_stream_wps_process(_adapter *padapter,
627
struct iw_request_info *info, struct wlan_network *pnetwork,
628
char *start, char *stop, struct iw_event *iwe)
629
{
630
/* parsing WPS IE */
631
uint cnt = 0, total_ielen;
632
u8 *wpsie_ptr = NULL;
633
uint wps_ielen = 0;
634
u8 ie_offset = (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);
635
636
u8 *ie_ptr = pnetwork->network.IEs + ie_offset;
637
total_ielen = pnetwork->network.IELength - ie_offset;
638
639
if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) { /* Probe Request */
640
ie_ptr = pnetwork->network.IEs;
641
total_ielen = pnetwork->network.IELength;
642
} else { /* Beacon or Probe Respones */
643
ie_ptr = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
644
total_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
645
}
646
while (cnt < total_ielen) {
647
if (rtw_is_wps_ie(&ie_ptr[cnt], &wps_ielen) && (wps_ielen > 2)) {
648
wpsie_ptr = &ie_ptr[cnt];
649
iwe->cmd = IWEVGENIE;
650
iwe->u.data.length = (u16)wps_ielen;
651
start = iwe_stream_add_point(info, start, stop, iwe, wpsie_ptr);
652
}
653
cnt += ie_ptr[cnt + 1] + 2; /* goto next */
654
}
655
return start;
656
}
657
658
static inline char *iwe_stream_wapi_process(_adapter *padapter,
659
struct iw_request_info *info, struct wlan_network *pnetwork,
660
char *start, char *stop, struct iw_event *iwe)
661
{
662
#ifdef CONFIG_WAPI_SUPPORT
663
char *p;
664
665
if (pnetwork->network.Reserved[0] != BSS_TYPE_PROB_REQ) { /* Probe Request */
666
sint out_len_wapi = 0;
667
/* here use static for stack size */
668
static u8 buf_wapi[MAX_WAPI_IE_LEN * 2] = {0};
669
static u8 wapi_ie[MAX_WAPI_IE_LEN] = {0};
670
u16 wapi_len = 0;
671
u16 i;
672
673
out_len_wapi = rtw_get_wapi_ie(pnetwork->network.IEs , pnetwork->network.IELength, wapi_ie, &wapi_len);
674
675
RTW_INFO("rtw_wx_get_scan: %s ", pnetwork->network.Ssid.Ssid);
676
RTW_INFO("rtw_wx_get_scan: ssid = %d ", wapi_len);
677
678
679
if (wapi_len > 0) {
680
p = buf_wapi;
681
/* _rtw_memset(buf_wapi, 0, MAX_WAPI_IE_LEN*2); */
682
p += sprintf(p, "wapi_ie=");
683
for (i = 0; i < wapi_len; i++)
684
p += sprintf(p, "%02x", wapi_ie[i]);
685
686
_rtw_memset(iwe, 0, sizeof(*iwe));
687
iwe->cmd = IWEVCUSTOM;
688
iwe->u.data.length = strlen(buf_wapi);
689
start = iwe_stream_add_point(info, start, stop, iwe, buf_wapi);
690
691
_rtw_memset(iwe, 0, sizeof(*iwe));
692
iwe->cmd = IWEVGENIE;
693
iwe->u.data.length = wapi_len;
694
start = iwe_stream_add_point(info, start, stop, iwe, wapi_ie);
695
}
696
}
697
#endif/* #ifdef CONFIG_WAPI_SUPPORT */
698
return start;
699
}
700
701
static inline char *iwe_stream_rssi_process(_adapter *padapter,
702
struct iw_request_info *info, struct wlan_network *pnetwork,
703
char *start, char *stop, struct iw_event *iwe)
704
{
705
u8 ss, sq;
706
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
707
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
708
s16 noise = 0;
709
#endif
710
711
/* Add quality statistics */
712
iwe->cmd = IWEVQUAL;
713
iwe->u.qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED
714
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
715
| IW_QUAL_NOISE_UPDATED
716
#else
717
| IW_QUAL_NOISE_INVALID
718
#endif
719
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
720
| IW_QUAL_DBM
721
#endif
722
;
723
724
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
725
is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
726
ss = padapter->recvpriv.signal_strength;
727
sq = padapter->recvpriv.signal_qual;
728
} else {
729
ss = pnetwork->network.PhyInfo.SignalStrength;
730
sq = pnetwork->network.PhyInfo.SignalQuality;
731
}
732
733
734
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
735
iwe->u.qual.level = (u8) translate_percentage_to_dbm(ss); /* dbm */
736
#else
737
iwe->u.qual.level = (u8)ss; /* % */
738
#endif
739
740
iwe->u.qual.qual = (u8)sq; /* signal quality */
741
742
#ifdef CONFIG_PLATFORM_ROCKCHIPS
743
iwe->u.qual.noise = -100; /* noise level suggest by zhf@rockchips */
744
#else
745
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
746
if (IS_NM_ENABLE(padapter)) {
747
noise = rtw_noise_query_by_chan_num(padapter, pnetwork->network.Configuration.DSConfig);
748
#ifndef CONFIG_SIGNAL_DISPLAY_DBM
749
noise = translate_dbm_to_percentage(noise);/*percentage*/
750
#endif
751
iwe->u.qual.noise = noise;
752
}
753
#else
754
iwe->u.qual.noise = 0; /* noise level */
755
#endif
756
#endif /* CONFIG_PLATFORM_ROCKCHIPS */
757
758
/* RTW_INFO("iqual=%d, ilevel=%d, inoise=%d, iupdated=%d\n", iwe.u.qual.qual, iwe.u.qual.level , iwe.u.qual.noise, iwe.u.qual.updated); */
759
760
start = iwe_stream_add_event(info, start, stop, iwe, IW_EV_QUAL_LEN);
761
return start;
762
}
763
764
static inline char *iwe_stream_net_rsv_process(_adapter *padapter,
765
struct iw_request_info *info, struct wlan_network *pnetwork,
766
char *start, char *stop, struct iw_event *iwe)
767
{
768
u8 buf[32] = {0};
769
u8 *p, *pos;
770
p = buf;
771
pos = pnetwork->network.Reserved;
772
773
p += sprintf(p, "fm=%02X%02X", pos[1], pos[0]);
774
_rtw_memset(iwe, 0, sizeof(*iwe));
775
iwe->cmd = IWEVCUSTOM;
776
iwe->u.data.length = strlen(buf);
777
start = iwe_stream_add_point(info, start, stop, iwe, buf);
778
return start;
779
}
780
781
static char *translate_scan(_adapter *padapter,
782
struct iw_request_info *info, struct wlan_network *pnetwork,
783
char *start, char *stop)
784
{
785
struct iw_event iwe;
786
u16 cap = 0;
787
_rtw_memset(&iwe, 0, sizeof(iwe));
788
789
if (_FALSE == search_p2p_wfd_ie(padapter, info, pnetwork, start, stop))
790
return start;
791
792
start = iwe_stream_mac_addr_proess(padapter, info, pnetwork, start, stop, &iwe);
793
start = iwe_stream_essid_proess(padapter, info, pnetwork, start, stop, &iwe);
794
start = iwe_stream_protocol_process(padapter, info, pnetwork, start, stop, &iwe);
795
if (pnetwork->network.Reserved[0] == BSS_TYPE_PROB_REQ) /* Probe Request */
796
cap = 0;
797
else {
798
_rtw_memcpy((u8 *)&cap, rtw_get_capability_from_ie(pnetwork->network.IEs), 2);
799
cap = le16_to_cpu(cap);
800
}
801
802
start = iwe_stream_mode_process(padapter, info, pnetwork, start, stop, &iwe, cap);
803
start = iwe_stream_chan_process(padapter, info, pnetwork, start, stop, &iwe);
804
start = iwe_stream_encryption_process(padapter, info, pnetwork, start, stop, &iwe, cap);
805
start = iwe_stream_rate_process(padapter, info, pnetwork, start, stop, &iwe);
806
start = iwe_stream_wpa_wpa2_process(padapter, info, pnetwork, start, stop, &iwe);
807
start = iwe_stream_wps_process(padapter, info, pnetwork, start, stop, &iwe);
808
start = iwe_stream_wapi_process(padapter, info, pnetwork, start, stop, &iwe);
809
start = iwe_stream_rssi_process(padapter, info, pnetwork, start, stop, &iwe);
810
start = iwe_stream_net_rsv_process(padapter, info, pnetwork, start, stop, &iwe);
811
812
return start;
813
}
814
815
static int wpa_set_auth_algs(struct net_device *dev, u32 value)
816
{
817
_adapter *padapter = (_adapter *) rtw_netdev_priv(dev);
818
int ret = 0;
819
820
if ((value & AUTH_ALG_SHARED_KEY) && (value & AUTH_ALG_OPEN_SYSTEM)) {
821
RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY and AUTH_ALG_OPEN_SYSTEM [value:0x%x]\n", value);
822
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
823
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
824
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
825
} else if (value & AUTH_ALG_SHARED_KEY) {
826
RTW_INFO("wpa_set_auth_algs, AUTH_ALG_SHARED_KEY [value:0x%x]\n", value);
827
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
828
829
#ifdef CONFIG_PLATFORM_MT53XX
830
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
831
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
832
#else
833
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeShared;
834
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
835
#endif
836
} else if (value & AUTH_ALG_OPEN_SYSTEM) {
837
RTW_INFO("wpa_set_auth_algs, AUTH_ALG_OPEN_SYSTEM\n");
838
/* padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled; */
839
if (padapter->securitypriv.ndisauthtype < Ndis802_11AuthModeWPAPSK) {
840
#ifdef CONFIG_PLATFORM_MT53XX
841
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeAutoSwitch;
842
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
843
#else
844
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
845
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
846
#endif
847
}
848
849
} else if (value & AUTH_ALG_LEAP)
850
RTW_INFO("wpa_set_auth_algs, AUTH_ALG_LEAP\n");
851
else {
852
RTW_INFO("wpa_set_auth_algs, error!\n");
853
ret = -EINVAL;
854
}
855
856
return ret;
857
858
}
859
860
static int wpa_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
861
{
862
int ret = 0;
863
u32 wep_key_idx, wep_key_len;
864
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
865
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
866
struct security_priv *psecuritypriv = &padapter->securitypriv;
867
#ifdef CONFIG_P2P
868
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
869
#endif /* CONFIG_P2P */
870
871
872
param->u.crypt.err = 0;
873
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
874
875
if (param_len < (u32)((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) {
876
ret = -EINVAL;
877
goto exit;
878
}
879
880
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
881
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
882
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
883
884
if (param->u.crypt.idx >= WEP_KEYS
885
#ifdef CONFIG_IEEE80211W
886
&& param->u.crypt.idx > BIP_MAX_KEYID
887
#endif /* CONFIG_IEEE80211W */
888
) {
889
ret = -EINVAL;
890
goto exit;
891
}
892
} else {
893
#ifdef CONFIG_WAPI_SUPPORT
894
if (strcmp(param->u.crypt.alg, "SMS4"))
895
#endif
896
{
897
ret = -EINVAL;
898
goto exit;
899
}
900
}
901
902
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
903
RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
904
905
wep_key_idx = param->u.crypt.idx;
906
wep_key_len = param->u.crypt.key_len;
907
908
if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
909
ret = -EINVAL;
910
goto exit;
911
}
912
913
if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
914
/* wep default key has not been set, so use this key index as default key.*/
915
916
wep_key_len = wep_key_len <= 5 ? 5 : 13;
917
918
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
919
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
920
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
921
922
if (wep_key_len == 13) {
923
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
924
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
925
}
926
927
psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
928
}
929
930
_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
931
932
psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
933
934
psecuritypriv->key_mask |= BIT(wep_key_idx);
935
936
padapter->mlmeextpriv.mlmext_info.key_index = wep_key_idx;
937
goto exit;
938
}
939
940
if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
941
struct sta_info *psta, *pbcmc_sta;
942
struct sta_priv *pstapriv = &padapter->stapriv;
943
944
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
945
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
946
if (psta == NULL) {
947
/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
948
} else {
949
/* Jeff: don't disable ieee8021x_blocked while clearing key */
950
if (strcmp(param->u.crypt.alg, "none") != 0)
951
psta->ieee8021x_blocked = _FALSE;
952
953
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
954
(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
955
psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
956
957
if (param->u.crypt.set_tx == 1) { /* pairwise key */
958
RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n"
959
, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
960
_rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
961
if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
962
_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
963
_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
964
padapter->securitypriv.busetkipkey = _FALSE;
965
}
966
psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
967
psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
968
psta->bpairwise_key_installed = _TRUE;
969
rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
970
971
} else { /* group key */
972
if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
973
RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"
974
, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
975
_rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,
976
(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
977
/* only TKIP group key need to install this */
978
if (param->u.crypt.key_len > 16) {
979
_rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
980
_rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
981
}
982
padapter->securitypriv.binstallGrpkey = _TRUE;
983
if (param->u.crypt.idx < 4)
984
_rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8);
985
padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
986
rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
987
988
#ifdef CONFIG_IEEE80211W
989
} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
990
RTW_INFO(FUNC_ADPT_FMT" set IGTK idx:%u, len:%u\n"
991
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
992
_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,
993
(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
994
psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
995
psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
996
psecuritypriv->binstallBIPkey = _TRUE;
997
#endif /* CONFIG_IEEE80211W */
998
999
}
1000
1001
#ifdef CONFIG_P2P
1002
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1003
rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1004
#endif /* CONFIG_P2P */
1005
1006
/* WPA/WPA2 key-handshake has completed */
1007
clr_fwstate(pmlmepriv, WIFI_UNDER_KEY_HANDSHAKE);
1008
}
1009
}
1010
1011
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1012
if (pbcmc_sta == NULL) {
1013
/* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
1014
} else {
1015
/* Jeff: don't disable ieee8021x_blocked while clearing key */
1016
if (strcmp(param->u.crypt.alg, "none") != 0)
1017
pbcmc_sta->ieee8021x_blocked = _FALSE;
1018
1019
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1020
(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1021
pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1022
}
1023
} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1024
}
1025
}
1026
1027
#ifdef CONFIG_WAPI_SUPPORT
1028
if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1029
rtw_wapi_set_set_encryption(padapter, param);
1030
#endif
1031
1032
exit:
1033
1034
1035
return ret;
1036
}
1037
1038
static int rtw_set_wpa_ie(_adapter *padapter, char *pie, unsigned short ielen)
1039
{
1040
u8 *buf = NULL, *pos = NULL;
1041
int group_cipher = 0, pairwise_cipher = 0;
1042
u8 mfp_opt = MFP_NO;
1043
int ret = 0;
1044
u8 null_addr[] = {0, 0, 0, 0, 0, 0};
1045
#ifdef CONFIG_P2P
1046
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1047
#endif /* CONFIG_P2P */
1048
1049
if ((ielen > MAX_WPA_IE_LEN) || (pie == NULL)) {
1050
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1051
if (pie == NULL)
1052
return ret;
1053
else
1054
return -EINVAL;
1055
}
1056
1057
if (ielen) {
1058
buf = rtw_zmalloc(ielen);
1059
if (buf == NULL) {
1060
ret = -ENOMEM;
1061
goto exit;
1062
}
1063
1064
_rtw_memcpy(buf, pie , ielen);
1065
1066
/* dump */
1067
{
1068
int i;
1069
RTW_INFO("\n wpa_ie(length:%d):\n", ielen);
1070
for (i = 0; i < ielen; i = i + 8)
1071
RTW_INFO("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]);
1072
}
1073
1074
pos = buf;
1075
if (ielen < RSN_HEADER_LEN) {
1076
ret = -1;
1077
goto exit;
1078
}
1079
1080
if (rtw_parse_wpa_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
1081
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1082
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
1083
_rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1084
}
1085
1086
if (rtw_parse_wpa2_ie(buf, ielen, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) {
1087
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
1088
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
1089
_rtw_memcpy(padapter->securitypriv.supplicant_ie, &buf[0], ielen);
1090
}
1091
1092
if (group_cipher == 0)
1093
group_cipher = WPA_CIPHER_NONE;
1094
if (pairwise_cipher == 0)
1095
pairwise_cipher = WPA_CIPHER_NONE;
1096
1097
switch (group_cipher) {
1098
case WPA_CIPHER_NONE:
1099
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
1100
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1101
break;
1102
case WPA_CIPHER_WEP40:
1103
padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
1104
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1105
break;
1106
case WPA_CIPHER_TKIP:
1107
padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
1108
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1109
break;
1110
case WPA_CIPHER_CCMP:
1111
padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
1112
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1113
break;
1114
case WPA_CIPHER_WEP104:
1115
padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
1116
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1117
break;
1118
}
1119
1120
switch (pairwise_cipher) {
1121
case WPA_CIPHER_NONE:
1122
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
1123
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
1124
break;
1125
case WPA_CIPHER_WEP40:
1126
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
1127
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1128
break;
1129
case WPA_CIPHER_TKIP:
1130
padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
1131
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
1132
break;
1133
case WPA_CIPHER_CCMP:
1134
padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
1135
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
1136
break;
1137
case WPA_CIPHER_WEP104:
1138
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
1139
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
1140
break;
1141
}
1142
1143
if (mfp_opt == MFP_INVALID) {
1144
RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));
1145
ret = -EINVAL;
1146
goto exit;
1147
}
1148
padapter->securitypriv.mfp_opt = mfp_opt;
1149
1150
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
1151
{/* set wps_ie */
1152
u16 cnt = 0;
1153
u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
1154
1155
while (cnt < ielen) {
1156
eid = buf[cnt];
1157
1158
if ((eid == _VENDOR_SPECIFIC_IE_) && (_rtw_memcmp(&buf[cnt + 2], wps_oui, 4) == _TRUE)) {
1159
RTW_INFO("SET WPS_IE\n");
1160
1161
padapter->securitypriv.wps_ie_len = ((buf[cnt + 1] + 2) < MAX_WPS_IE_LEN) ? (buf[cnt + 1] + 2) : MAX_WPS_IE_LEN;
1162
1163
_rtw_memcpy(padapter->securitypriv.wps_ie, &buf[cnt], padapter->securitypriv.wps_ie_len);
1164
1165
set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
1166
1167
#ifdef CONFIG_P2P
1168
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_OK))
1169
rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_ING);
1170
#endif /* CONFIG_P2P */
1171
cnt += buf[cnt + 1] + 2;
1172
1173
break;
1174
} else {
1175
cnt += buf[cnt + 1] + 2; /* goto next */
1176
}
1177
}
1178
}
1179
}
1180
1181
/* TKIP and AES disallow multicast packets until installing group key */
1182
if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
1183
|| padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
1184
|| padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
1185
/* WPS open need to enable multicast
1186
* || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
1187
rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
1188
1189
1190
exit:
1191
1192
if (buf)
1193
rtw_mfree(buf, ielen);
1194
1195
return ret;
1196
}
1197
1198
static int rtw_wx_get_name(struct net_device *dev,
1199
struct iw_request_info *info,
1200
union iwreq_data *wrqu, char *extra)
1201
{
1202
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1203
u32 ht_ielen = 0;
1204
char *p;
1205
u8 ht_cap = _FALSE, vht_cap = _FALSE;
1206
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1207
WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1208
NDIS_802_11_RATES_EX *prates = NULL;
1209
1210
1211
1212
if (check_fwstate(pmlmepriv, _FW_LINKED | WIFI_ADHOC_MASTER_STATE) == _TRUE) {
1213
/* parsing HT_CAP_IE */
1214
if( is_supported_ht(padapter->registrypriv.wireless_mode)&&(padapter->registrypriv.ht_enable)) {
1215
p = rtw_get_ie(&pcur_bss->IEs[12], _HT_CAPABILITY_IE_, &ht_ielen, pcur_bss->IELength - 12);
1216
if (p && ht_ielen > 0 )
1217
ht_cap = _TRUE;
1218
}
1219
#ifdef CONFIG_80211AC_VHT
1220
if ((padapter->registrypriv.wireless_mode & WIRELESS_11AC) &&
1221
(pmlmepriv->vhtpriv.vht_option == _TRUE))
1222
vht_cap = _TRUE;
1223
#endif
1224
1225
prates = &pcur_bss->SupportedRates;
1226
if (rtw_is_cckratesonly_included((u8 *)prates) == _TRUE) {
1227
if (ht_cap == _TRUE)
1228
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bn");
1229
else
1230
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1231
} else if ((rtw_is_cckrates_included((u8 *)prates)) == _TRUE) {
1232
if (ht_cap == _TRUE)
1233
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bgn");
1234
else {
1235
if(padapter->registrypriv.wireless_mode & WIRELESS_11G)
1236
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11bg");
1237
else
1238
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11b");
1239
}
1240
} else {
1241
if (pcur_bss->Configuration.DSConfig > 14) {
1242
#ifdef CONFIG_80211AC_VHT
1243
if (vht_cap == _TRUE)
1244
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11AC");
1245
else
1246
#endif
1247
{
1248
if (ht_cap == _TRUE)
1249
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11an");
1250
else
1251
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11a");
1252
}
1253
} else {
1254
if (ht_cap == _TRUE)
1255
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11gn");
1256
else
1257
snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g");
1258
}
1259
}
1260
} else {
1261
/* prates = &padapter->registrypriv.dev_network.SupportedRates; */
1262
/* snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11g"); */
1263
snprintf(wrqu->name, IFNAMSIZ, "unassociated");
1264
}
1265
1266
1267
return 0;
1268
}
1269
1270
static int rtw_wx_set_freq(struct net_device *dev,
1271
struct iw_request_info *info,
1272
union iwreq_data *wrqu, char *extra)
1273
{
1274
1275
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1276
int exp = 1, freq = 0, div = 0;
1277
1278
rtw_ps_deny(padapter, PS_DENY_IOCTL);
1279
if (rtw_pwr_wakeup(padapter) == _FALSE)
1280
goto exit;
1281
if (wrqu->freq.m <= 1000) {
1282
if (wrqu->freq.flags == IW_FREQ_AUTO) {
1283
if (rtw_chset_search_ch(adapter_to_chset(padapter), wrqu->freq.m) > 0) {
1284
padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1285
RTW_INFO("%s: channel is auto, set to channel %d\n", __func__, wrqu->freq.m);
1286
} else {
1287
padapter->mlmeextpriv.cur_channel = 1;
1288
RTW_INFO("%s: channel is auto, Channel Plan don't match just set to channel 1\n", __func__);
1289
}
1290
} else {
1291
padapter->mlmeextpriv.cur_channel = wrqu->freq.m;
1292
RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1293
}
1294
} else {
1295
while (wrqu->freq.e) {
1296
exp *= 10;
1297
wrqu->freq.e--;
1298
}
1299
1300
freq = wrqu->freq.m;
1301
1302
while (!(freq % 10)) {
1303
freq /= 10;
1304
exp *= 10;
1305
}
1306
1307
/* freq unit is MHz here */
1308
div = 1000000 / exp;
1309
1310
if (div)
1311
freq /= div;
1312
else {
1313
div = exp / 1000000;
1314
freq *= div;
1315
}
1316
1317
/* If freq is invalid, rtw_freq2ch() will return channel 1 */
1318
padapter->mlmeextpriv.cur_channel = rtw_freq2ch(freq);
1319
RTW_INFO("%s: set to channel %d\n", __func__, padapter->mlmeextpriv.cur_channel);
1320
}
1321
set_channel_bwmode(padapter, padapter->mlmeextpriv.cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
1322
exit:
1323
rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
1324
1325
return 0;
1326
}
1327
1328
static int rtw_wx_get_freq(struct net_device *dev,
1329
struct iw_request_info *info,
1330
union iwreq_data *wrqu, char *extra)
1331
{
1332
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1333
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1334
WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1335
1336
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE && check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1337
1338
wrqu->freq.m = rtw_ch2freq(pcur_bss->Configuration.DSConfig) * 100000;
1339
wrqu->freq.e = 1;
1340
wrqu->freq.i = pcur_bss->Configuration.DSConfig;
1341
1342
} else {
1343
wrqu->freq.m = rtw_ch2freq(padapter->mlmeextpriv.cur_channel) * 100000;
1344
wrqu->freq.e = 1;
1345
wrqu->freq.i = padapter->mlmeextpriv.cur_channel;
1346
}
1347
1348
return 0;
1349
}
1350
1351
static int rtw_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
1352
union iwreq_data *wrqu, char *b)
1353
{
1354
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1355
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1356
NDIS_802_11_NETWORK_INFRASTRUCTURE networkType ;
1357
int ret = 0;
1358
1359
1360
if (_FAIL == rtw_pwr_wakeup(padapter)) {
1361
ret = -EPERM;
1362
goto exit;
1363
}
1364
1365
if (!rtw_is_hw_init_completed(padapter)) {
1366
ret = -EPERM;
1367
goto exit;
1368
}
1369
1370
/* initial default type */
1371
dev->type = ARPHRD_ETHER;
1372
1373
if (wrqu->mode == IW_MODE_MONITOR) {
1374
rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE);
1375
LeaveAllPowerSaveMode(padapter);
1376
} else {
1377
rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE);
1378
}
1379
1380
switch (wrqu->mode) {
1381
case IW_MODE_MONITOR:
1382
networkType = Ndis802_11Monitor;
1383
#if 0
1384
dev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
1385
#endif
1386
1387
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
1388
dev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
1389
RTW_INFO("set_mode = IW_MODE_MONITOR\n");
1390
#else
1391
RTW_INFO("kernel version < 2.6.24 not support IW_MODE_MONITOR\n");
1392
#endif
1393
break;
1394
1395
case IW_MODE_AUTO:
1396
networkType = Ndis802_11AutoUnknown;
1397
RTW_INFO("set_mode = IW_MODE_AUTO\n");
1398
break;
1399
case IW_MODE_ADHOC:
1400
networkType = Ndis802_11IBSS;
1401
RTW_INFO("set_mode = IW_MODE_ADHOC\n");
1402
break;
1403
case IW_MODE_MASTER:
1404
networkType = Ndis802_11APMode;
1405
RTW_INFO("set_mode = IW_MODE_MASTER\n");
1406
break;
1407
case IW_MODE_INFRA:
1408
networkType = Ndis802_11Infrastructure;
1409
RTW_INFO("set_mode = IW_MODE_INFRA\n");
1410
break;
1411
1412
default:
1413
ret = -EINVAL;;
1414
goto exit;
1415
}
1416
1417
if (rtw_set_802_11_infrastructure_mode(padapter, networkType, 0) == _FALSE) {
1418
1419
ret = -EPERM;
1420
goto exit;
1421
1422
}
1423
1424
rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
1425
1426
if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1427
rtw_indicate_connect(padapter);
1428
1429
exit:
1430
1431
1432
return ret;
1433
1434
}
1435
1436
static int rtw_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
1437
union iwreq_data *wrqu, char *b)
1438
{
1439
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1440
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1441
1442
1443
1444
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1445
wrqu->mode = IW_MODE_INFRA;
1446
else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) ||
1447
(check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE))
1448
1449
wrqu->mode = IW_MODE_ADHOC;
1450
else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1451
wrqu->mode = IW_MODE_MASTER;
1452
else if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
1453
wrqu->mode = IW_MODE_MONITOR;
1454
else
1455
wrqu->mode = IW_MODE_AUTO;
1456
1457
1458
return 0;
1459
1460
}
1461
1462
1463
static int rtw_wx_set_pmkid(struct net_device *dev,
1464
struct iw_request_info *a,
1465
union iwreq_data *wrqu, char *extra)
1466
{
1467
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1468
u8 j, blInserted = _FALSE;
1469
int intReturn = _FALSE;
1470
struct security_priv *psecuritypriv = &padapter->securitypriv;
1471
struct iw_pmksa *pPMK = (struct iw_pmksa *) extra;
1472
u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
1473
u8 strIssueBssid[ETH_ALEN] = { 0x00 };
1474
1475
#if 0
1476
struct iw_pmksa {
1477
__u32 cmd;
1478
struct sockaddr bssid;
1479
__u8 pmkid[IW_PMKID_LEN]; /* IW_PMKID_LEN=16 */
1480
}
1481
There are the BSSID information in the bssid.sa_data array.
1482
If cmd is IW_PMKSA_FLUSH, it means the wpa_suppplicant wants to clear all the PMKID information.
1483
If cmd is IW_PMKSA_ADD, it means the wpa_supplicant wants to add a PMKID / BSSID to driver.
1484
If cmd is IW_PMKSA_REMOVE, it means the wpa_supplicant wants to remove a PMKID / BSSID from driver.
1485
#endif
1486
1487
_rtw_memcpy(strIssueBssid, pPMK->bssid.sa_data, ETH_ALEN);
1488
if (pPMK->cmd == IW_PMKSA_ADD) {
1489
RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_ADD!\n");
1490
if (_rtw_memcmp(strIssueBssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
1491
return intReturn ;
1492
else
1493
intReturn = _TRUE;
1494
blInserted = _FALSE;
1495
1496
/* overwrite PMKID */
1497
for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1498
if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1499
/* BSSID is matched, the same AP => rewrite with new PMKID. */
1500
1501
RTW_INFO("[rtw_wx_set_pmkid] BSSID exists in the PMKList.\n");
1502
1503
_rtw_memcpy(psecuritypriv->PMKIDList[j].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1504
psecuritypriv->PMKIDList[j].bUsed = _TRUE;
1505
psecuritypriv->PMKIDIndex = j + 1;
1506
blInserted = _TRUE;
1507
break;
1508
}
1509
}
1510
1511
if (!blInserted) {
1512
/* Find a new entry */
1513
RTW_INFO("[rtw_wx_set_pmkid] Use the new entry index = %d for this PMKID.\n",
1514
psecuritypriv->PMKIDIndex);
1515
1516
_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, strIssueBssid, ETH_ALEN);
1517
_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pPMK->pmkid, IW_PMKID_LEN);
1518
1519
psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
1520
psecuritypriv->PMKIDIndex++ ;
1521
if (psecuritypriv->PMKIDIndex == 16)
1522
psecuritypriv->PMKIDIndex = 0;
1523
}
1524
} else if (pPMK->cmd == IW_PMKSA_REMOVE) {
1525
RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_REMOVE!\n");
1526
intReturn = _TRUE;
1527
for (j = 0 ; j < NUM_PMKID_CACHE; j++) {
1528
if (_rtw_memcmp(psecuritypriv->PMKIDList[j].Bssid, strIssueBssid, ETH_ALEN) == _TRUE) {
1529
/* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
1530
_rtw_memset(psecuritypriv->PMKIDList[j].Bssid, 0x00, ETH_ALEN);
1531
psecuritypriv->PMKIDList[j].bUsed = _FALSE;
1532
break;
1533
}
1534
}
1535
} else if (pPMK->cmd == IW_PMKSA_FLUSH) {
1536
RTW_INFO("[rtw_wx_set_pmkid] IW_PMKSA_FLUSH!\n");
1537
_rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
1538
psecuritypriv->PMKIDIndex = 0;
1539
intReturn = _TRUE;
1540
}
1541
return intReturn ;
1542
}
1543
1544
static int rtw_wx_get_sens(struct net_device *dev,
1545
struct iw_request_info *info,
1546
union iwreq_data *wrqu, char *extra)
1547
{
1548
#ifdef CONFIG_PLATFORM_ROCKCHIPS
1549
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1550
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1551
1552
/*
1553
* 20110311 Commented by Jeff
1554
* For rockchip platform's wpa_driver_wext_get_rssi
1555
*/
1556
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) {
1557
/* wrqu->sens.value=-padapter->recvpriv.signal_strength; */
1558
wrqu->sens.value = -padapter->recvpriv.rssi;
1559
/* RTW_INFO("%s: %d\n", __FUNCTION__, wrqu->sens.value); */
1560
wrqu->sens.fixed = 0; /* no auto select */
1561
} else
1562
#endif
1563
{
1564
wrqu->sens.value = 0;
1565
wrqu->sens.fixed = 0; /* no auto select */
1566
wrqu->sens.disabled = 1;
1567
}
1568
return 0;
1569
}
1570
1571
static int rtw_wx_get_range(struct net_device *dev,
1572
struct iw_request_info *info,
1573
union iwreq_data *wrqu, char *extra)
1574
{
1575
struct iw_range *range = (struct iw_range *)extra;
1576
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1577
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
1578
u16 val;
1579
int i;
1580
1581
1582
1583
wrqu->data.length = sizeof(*range);
1584
_rtw_memset(range, 0, sizeof(*range));
1585
1586
/* Let's try to keep this struct in the same order as in
1587
* linux/include/wireless.h
1588
*/
1589
1590
/* TODO: See what values we can set, and remove the ones we can't
1591
* set, or fill them with some default data.
1592
*/
1593
1594
/* ~5 Mb/s real (802.11b) */
1595
range->throughput = 5 * 1000 * 1000;
1596
1597
/* TODO: Not used in 802.11b?
1598
* range->min_nwid; Minimal NWID we are able to set */
1599
/* TODO: Not used in 802.11b?
1600
* range->max_nwid; Maximal NWID we are able to set */
1601
1602
/* Old Frequency (backward compat - moved lower ) */
1603
/* range->old_num_channels;
1604
* range->old_num_frequency;
1605
* range->old_freq[6]; Filler to keep "version" at the same offset */
1606
1607
/* signal level threshold range */
1608
1609
/* Quality of link & SNR stuff */
1610
/* Quality range (link, level, noise)
1611
* If the quality is absolute, it will be in the range [0 ; max_qual],
1612
* if the quality is dBm, it will be in the range [max_qual ; 0].
1613
* Don't forget that we use 8 bit arithmetics...
1614
*
1615
* If percentage range is 0~100
1616
* Signal strength dbm range logical is -100 ~ 0
1617
* but usually value is -90 ~ -20
1618
*/
1619
range->max_qual.qual = 100;
1620
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
1621
range->max_qual.level = (u8)-100;
1622
range->max_qual.noise = (u8)-100;
1623
range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1624
range->max_qual.updated |= IW_QUAL_DBM;
1625
#else /* !CONFIG_SIGNAL_DISPLAY_DBM */
1626
/* percent values between 0 and 100. */
1627
range->max_qual.level = 100;
1628
range->max_qual.noise = 100;
1629
range->max_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1630
#endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
1631
1632
/* This should contain the average/typical values of the quality
1633
* indicator. This should be the threshold between a "good" and
1634
* a "bad" link (example : monitor going from green to orange).
1635
* Currently, user space apps like quality monitors don't have any
1636
* way to calibrate the measurement. With this, they can split
1637
* the range between 0 and max_qual in different quality level
1638
* (using a geometric subdivision centered on the average).
1639
* I expect that people doing the user space apps will feedback
1640
* us on which value we need to put in each driver... */
1641
range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
1642
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
1643
/* TODO: Find real 'good' to 'bad' threshold value for RSSI */
1644
range->avg_qual.level = (u8)-70;
1645
range->avg_qual.noise = 0;
1646
range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1647
range->avg_qual.updated |= IW_QUAL_DBM;
1648
#else /* !CONFIG_SIGNAL_DISPLAY_DBM */
1649
/* TODO: Find real 'good' to 'bad' threshol value for RSSI */
1650
range->avg_qual.level = 30;
1651
range->avg_qual.noise = 100;
1652
range->avg_qual.updated = IW_QUAL_ALL_UPDATED; /* Updated all three */
1653
#endif /* !CONFIG_SIGNAL_DISPLAY_DBM */
1654
1655
range->num_bitrates = RATE_COUNT;
1656
1657
for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
1658
range->bitrate[i] = rtw_rates[i];
1659
1660
range->min_frag = MIN_FRAG_THRESHOLD;
1661
range->max_frag = MAX_FRAG_THRESHOLD;
1662
1663
range->pm_capa = 0;
1664
1665
range->we_version_compiled = WIRELESS_EXT;
1666
range->we_version_source = 16;
1667
1668
/* range->retry_capa; What retry options are supported
1669
* range->retry_flags; How to decode max/min retry limit
1670
* range->r_time_flags; How to decode max/min retry life
1671
* range->min_retry; Minimal number of retries
1672
* range->max_retry; Maximal number of retries
1673
* range->min_r_time; Minimal retry lifetime
1674
* range->max_r_time; Maximal retry lifetime */
1675
1676
for (i = 0, val = 0; i < rfctl->max_chan_nums; i++) {
1677
1678
/* Include only legal frequencies for some countries */
1679
if (rfctl->channel_set[i].ChannelNum != 0) {
1680
range->freq[val].i = rfctl->channel_set[i].ChannelNum;
1681
range->freq[val].m = rtw_ch2freq(rfctl->channel_set[i].ChannelNum) * 100000;
1682
range->freq[val].e = 1;
1683
val++;
1684
}
1685
1686
if (val == IW_MAX_FREQUENCIES)
1687
break;
1688
}
1689
1690
range->num_channels = val;
1691
range->num_frequency = val;
1692
1693
/* Commented by Albert 2009/10/13
1694
* The following code will proivde the security capability to network manager.
1695
* If the driver doesn't provide this capability to network manager,
1696
* the WPA/WPA2 routers can't be choosen in the network manager. */
1697
1698
/*
1699
#define IW_SCAN_CAPA_NONE 0x00
1700
#define IW_SCAN_CAPA_ESSID 0x01
1701
#define IW_SCAN_CAPA_BSSID 0x02
1702
#define IW_SCAN_CAPA_CHANNEL 0x04
1703
#define IW_SCAN_CAPA_MODE 0x08
1704
#define IW_SCAN_CAPA_RATE 0x10
1705
#define IW_SCAN_CAPA_TYPE 0x20
1706
#define IW_SCAN_CAPA_TIME 0x40
1707
*/
1708
1709
#if WIRELESS_EXT > 17
1710
range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
1711
IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
1712
#endif
1713
1714
#ifdef IW_SCAN_CAPA_ESSID /* WIRELESS_EXT > 21 */
1715
range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE | IW_SCAN_CAPA_BSSID |
1716
IW_SCAN_CAPA_CHANNEL | IW_SCAN_CAPA_MODE | IW_SCAN_CAPA_RATE;
1717
#endif
1718
1719
1720
1721
return 0;
1722
1723
}
1724
1725
/* set bssid flow
1726
* s1. rtw_set_802_11_infrastructure_mode()
1727
* s2. rtw_set_802_11_authentication_mode()
1728
* s3. set_802_11_encryption_mode()
1729
* s4. rtw_set_802_11_bssid() */
1730
static int rtw_wx_set_wap(struct net_device *dev,
1731
struct iw_request_info *info,
1732
union iwreq_data *awrq,
1733
char *extra)
1734
{
1735
_irqL irqL;
1736
uint ret = 0;
1737
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1738
struct sockaddr *temp = (struct sockaddr *)awrq;
1739
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1740
_list *phead;
1741
u8 *dst_bssid, *src_bssid;
1742
_queue *queue = &(pmlmepriv->scanned_queue);
1743
struct wlan_network *pnetwork = NULL;
1744
NDIS_802_11_AUTHENTICATION_MODE authmode;
1745
1746
/*
1747
#ifdef CONFIG_CONCURRENT_MODE
1748
if(padapter->adapter_type > PRIMARY_IFACE)
1749
{
1750
ret = -EINVAL;
1751
goto exit;
1752
}
1753
#endif
1754
*/
1755
1756
#ifdef CONFIG_CONCURRENT_MODE
1757
if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {
1758
RTW_INFO("set bssid, but buddy_intf is under scanning or linking\n");
1759
1760
ret = -EINVAL;
1761
1762
goto exit;
1763
}
1764
#endif
1765
1766
rtw_ps_deny(padapter, PS_DENY_JOIN);
1767
if (_FAIL == rtw_pwr_wakeup(padapter)) {
1768
ret = -1;
1769
goto cancel_ps_deny;
1770
}
1771
1772
if (!padapter->bup) {
1773
ret = -1;
1774
goto cancel_ps_deny;
1775
}
1776
1777
1778
if (temp->sa_family != ARPHRD_ETHER) {
1779
ret = -EINVAL;
1780
goto cancel_ps_deny;
1781
}
1782
1783
authmode = padapter->securitypriv.ndisauthtype;
1784
_enter_critical_bh(&queue->lock, &irqL);
1785
phead = get_list_head(queue);
1786
pmlmepriv->pscanned = get_next(phead);
1787
1788
while (1) {
1789
1790
if ((rtw_end_of_queue_search(phead, pmlmepriv->pscanned)) == _TRUE) {
1791
#if 0
1792
ret = -EINVAL;
1793
goto cancel_ps_deny;
1794
1795
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
1796
rtw_set_802_11_bssid(padapter, temp->sa_data);
1797
goto cancel_ps_deny;
1798
} else {
1799
ret = -EINVAL;
1800
goto cancel_ps_deny;
1801
}
1802
#endif
1803
1804
break;
1805
}
1806
1807
pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
1808
1809
pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
1810
1811
dst_bssid = pnetwork->network.MacAddress;
1812
1813
src_bssid = temp->sa_data;
1814
1815
if ((_rtw_memcmp(dst_bssid, src_bssid, ETH_ALEN)) == _TRUE) {
1816
if (!rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0)) {
1817
ret = -1;
1818
_exit_critical_bh(&queue->lock, &irqL);
1819
goto cancel_ps_deny;
1820
}
1821
1822
break;
1823
}
1824
1825
}
1826
_exit_critical_bh(&queue->lock, &irqL);
1827
1828
rtw_set_802_11_authentication_mode(padapter, authmode);
1829
/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
1830
if (rtw_set_802_11_bssid(padapter, temp->sa_data) == _FALSE) {
1831
ret = -1;
1832
goto cancel_ps_deny;
1833
}
1834
1835
cancel_ps_deny:
1836
rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
1837
1838
#ifdef CONFIG_CONCURRENT_MODE
1839
exit:
1840
#endif
1841
return ret;
1842
}
1843
1844
static int rtw_wx_get_wap(struct net_device *dev,
1845
struct iw_request_info *info,
1846
union iwreq_data *wrqu, char *extra)
1847
{
1848
1849
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1850
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
1851
WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
1852
1853
wrqu->ap_addr.sa_family = ARPHRD_ETHER;
1854
1855
_rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1856
1857
1858
1859
if (((check_fwstate(pmlmepriv, _FW_LINKED)) == _TRUE) ||
1860
((check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) == _TRUE) ||
1861
((check_fwstate(pmlmepriv, WIFI_AP_STATE)) == _TRUE))
1862
1863
_rtw_memcpy(wrqu->ap_addr.sa_data, pcur_bss->MacAddress, ETH_ALEN);
1864
else
1865
_rtw_memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
1866
1867
1868
return 0;
1869
1870
}
1871
1872
static int rtw_wx_set_mlme(struct net_device *dev,
1873
struct iw_request_info *info,
1874
union iwreq_data *wrqu, char *extra)
1875
{
1876
#if 0
1877
/* SIOCSIWMLME data */
1878
struct iw_mlme {
1879
__u16 cmd; /* IW_MLME_* */
1880
__u16 reason_code;
1881
struct sockaddr addr;
1882
};
1883
#endif
1884
1885
int ret = 0;
1886
u16 reason;
1887
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1888
struct iw_mlme *mlme = (struct iw_mlme *) extra;
1889
1890
1891
if (mlme == NULL)
1892
return -1;
1893
1894
RTW_INFO("%s\n", __FUNCTION__);
1895
1896
reason = cpu_to_le16(mlme->reason_code);
1897
1898
1899
RTW_INFO("%s, cmd=%d, reason=%d\n", __FUNCTION__, mlme->cmd, reason);
1900
1901
1902
switch (mlme->cmd) {
1903
case IW_MLME_DEAUTH:
1904
if (!rtw_set_802_11_disassociate(padapter))
1905
ret = -1;
1906
break;
1907
1908
case IW_MLME_DISASSOC:
1909
if (!rtw_set_802_11_disassociate(padapter))
1910
ret = -1;
1911
1912
break;
1913
1914
default:
1915
return -EOPNOTSUPP;
1916
}
1917
#ifdef CONFIG_RTW_REPEATER_SON
1918
rtw_rson_do_disconnect(padapter);
1919
#endif
1920
return ret;
1921
}
1922
1923
static int rtw_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
1924
union iwreq_data *wrqu, char *extra)
1925
{
1926
u8 _status = _FALSE;
1927
int ret = 0;
1928
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1929
/*struct mlme_priv *pmlmepriv = &padapter->mlmepriv;*/
1930
struct sitesurvey_parm parm;
1931
u8 ssc_chk;
1932
#ifdef CONFIG_P2P
1933
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1934
#endif /* CONFIG_P2P */
1935
1936
#ifdef DBG_IOCTL
1937
RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
1938
#endif
1939
1940
#if 1
1941
ssc_chk = rtw_sitesurvey_condition_check(padapter, _FALSE);
1942
1943
#ifdef CONFIG_DOSCAN_IN_BUSYTRAFFIC
1944
if ((ssc_chk != SS_ALLOW) && (ssc_chk != SS_DENY_BUSY_TRAFFIC))
1945
#else
1946
/* When Busy Traffic, driver do not site survey. So driver return success. */
1947
/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
1948
/* modify by thomas 2011-02-22. */
1949
if (ssc_chk != SS_ALLOW)
1950
#endif
1951
{
1952
if (ssc_chk == SS_DENY_MP_MODE)
1953
ret = -EPERM;
1954
#ifdef DBG_LA_MODE
1955
else if (ssc_chk == SS_DENY_LA_MODE)
1956
ret = -EPERM;
1957
#endif
1958
else
1959
indicate_wx_scan_complete_event(padapter);
1960
1961
goto exit;
1962
} else
1963
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1964
1965
rtw_ps_deny(padapter, PS_DENY_SCAN);
1966
if (_FAIL == rtw_pwr_wakeup(padapter)) {
1967
ret = -1;
1968
goto cancel_ps_deny;
1969
}
1970
if (!rtw_is_adapter_up(padapter)) {
1971
ret = -1;
1972
goto cancel_ps_deny;
1973
}
1974
#else
1975
1976
#ifdef CONFIG_MP_INCLUDED
1977
if (rtw_mp_mode_check(padapter)) {
1978
RTW_INFO("MP mode block Scan request\n");
1979
ret = -EPERM;
1980
goto exit;
1981
}
1982
#endif
1983
if (rtw_is_scan_deny(padapter)) {
1984
indicate_wx_scan_complete_event(padapter);
1985
goto exit;
1986
}
1987
1988
rtw_ps_deny(padapter, PS_DENY_SCAN);
1989
if (_FAIL == rtw_pwr_wakeup(padapter)) {
1990
ret = -1;
1991
goto cancel_ps_deny;
1992
}
1993
1994
if (!rtw_is_adapter_up(padapter)) {
1995
ret = -1;
1996
goto cancel_ps_deny;
1997
}
1998
1999
#ifndef CONFIG_DOSCAN_IN_BUSYTRAFFIC
2000
/* When Busy Traffic, driver do not site survey. So driver return success. */
2001
/* wpa_supplicant will not issue SIOCSIWSCAN cmd again after scan timeout. */
2002
/* modify by thomas 2011-02-22. */
2003
if (rtw_mi_busy_traffic_check(padapter, _FALSE)) {
2004
indicate_wx_scan_complete_event(padapter);
2005
goto cancel_ps_deny;
2006
}
2007
#endif
2008
#ifdef CONFIG_RTW_REPEATER_SON
2009
if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {
2010
RTW_INFO(FUNC_ADPT_FMT" blocking scan for under rson scanning process\n", FUNC_ADPT_ARG(padapter));
2011
indicate_wx_scan_complete_event(padapter);
2012
goto cancel_ps_deny;
2013
}
2014
#endif
2015
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) && check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
2016
RTW_INFO("AP mode process WPS\n");
2017
indicate_wx_scan_complete_event(padapter);
2018
goto cancel_ps_deny;
2019
}
2020
2021
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {
2022
indicate_wx_scan_complete_event(padapter);
2023
goto cancel_ps_deny;
2024
}
2025
2026
#ifdef CONFIG_CONCURRENT_MODE
2027
if (rtw_mi_buddy_check_fwstate(padapter,
2028
_FW_UNDER_SURVEY | _FW_UNDER_LINKING | WIFI_UNDER_WPS)) {
2029
2030
indicate_wx_scan_complete_event(padapter);
2031
goto cancel_ps_deny;
2032
}
2033
#endif
2034
#endif
2035
2036
#ifdef CONFIG_P2P
2037
if (pwdinfo->p2p_state != P2P_STATE_NONE) {
2038
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2039
rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
2040
rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_FULL);
2041
rtw_free_network_queue(padapter, _TRUE);
2042
}
2043
#endif /* CONFIG_P2P */
2044
2045
#if WIRELESS_EXT >= 17
2046
if (wrqu->data.length == sizeof(struct iw_scan_req)) {
2047
struct iw_scan_req *req = (struct iw_scan_req *)extra;
2048
2049
if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
2050
int len = min((int)req->essid_len, IW_ESSID_MAX_SIZE);
2051
2052
rtw_init_sitesurvey_parm(padapter, &parm);
2053
_rtw_memcpy(&parm.ssid[0].Ssid, &req->essid, len);
2054
parm.ssid[0].SsidLength = len;
2055
parm.ssid_num = 1;
2056
2057
RTW_INFO("IW_SCAN_THIS_ESSID, ssid=%s, len=%d\n", req->essid, req->essid_len);
2058
2059
_status = rtw_set_802_11_bssid_list_scan(padapter, &parm);
2060
2061
} else if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
2062
RTW_INFO("rtw_wx_set_scan, req->scan_type == IW_SCAN_TYPE_PASSIVE\n");
2063
2064
} else
2065
#endif
2066
2067
if (wrqu->data.length >= WEXT_CSCAN_HEADER_SIZE
2068
&& _rtw_memcmp(extra, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
2069
) {
2070
int len = wrqu->data.length - WEXT_CSCAN_HEADER_SIZE;
2071
char *pos = extra + WEXT_CSCAN_HEADER_SIZE;
2072
char section;
2073
char sec_len;
2074
int ssid_index = 0;
2075
2076
/* RTW_INFO("%s COMBO_SCAN header is recognized\n", __FUNCTION__); */
2077
rtw_init_sitesurvey_parm(padapter, &parm);
2078
2079
while (len >= 1) {
2080
section = *(pos++);
2081
len -= 1;
2082
2083
switch (section) {
2084
case WEXT_CSCAN_SSID_SECTION:
2085
/* RTW_INFO("WEXT_CSCAN_SSID_SECTION\n"); */
2086
if (len < 1) {
2087
len = 0;
2088
break;
2089
}
2090
2091
sec_len = *(pos++);
2092
len -= 1;
2093
2094
if (sec_len > 0 && sec_len <= len) {
2095
2096
parm.ssid[ssid_index].SsidLength = sec_len;
2097
_rtw_memcpy(&parm.ssid[ssid_index].Ssid, pos, sec_len);
2098
2099
/* RTW_INFO("%s COMBO_SCAN with specific parm.ssid:%s, %d\n", __FUNCTION__ */
2100
/* , parm.ssid[ssid_index].Ssid, parm.ssid[ssid_index].SsidLength); */
2101
ssid_index++;
2102
}
2103
2104
pos += sec_len;
2105
len -= sec_len;
2106
break;
2107
2108
2109
case WEXT_CSCAN_CHANNEL_SECTION:
2110
/* RTW_INFO("WEXT_CSCAN_CHANNEL_SECTION\n"); */
2111
pos += 1;
2112
len -= 1;
2113
break;
2114
case WEXT_CSCAN_ACTV_DWELL_SECTION:
2115
/* RTW_INFO("WEXT_CSCAN_ACTV_DWELL_SECTION\n"); */
2116
pos += 2;
2117
len -= 2;
2118
break;
2119
case WEXT_CSCAN_PASV_DWELL_SECTION:
2120
/* RTW_INFO("WEXT_CSCAN_PASV_DWELL_SECTION\n"); */
2121
pos += 2;
2122
len -= 2;
2123
break;
2124
case WEXT_CSCAN_HOME_DWELL_SECTION:
2125
/* RTW_INFO("WEXT_CSCAN_HOME_DWELL_SECTION\n"); */
2126
pos += 2;
2127
len -= 2;
2128
break;
2129
case WEXT_CSCAN_TYPE_SECTION:
2130
/* RTW_INFO("WEXT_CSCAN_TYPE_SECTION\n"); */
2131
pos += 1;
2132
len -= 1;
2133
break;
2134
#if 0
2135
case WEXT_CSCAN_NPROBE_SECTION:
2136
RTW_INFO("WEXT_CSCAN_NPROBE_SECTION\n");
2137
break;
2138
#endif
2139
2140
default:
2141
/* RTW_INFO("Unknown CSCAN section %c\n", section); */
2142
len = 0; /* stop parsing */
2143
}
2144
/* RTW_INFO("len:%d\n", len); */
2145
2146
}
2147
parm.ssid_num = ssid_index;
2148
2149
/* jeff: it has still some scan paramater to parse, we only do this now... */
2150
_status = rtw_set_802_11_bssid_list_scan(padapter, &parm);
2151
2152
} else
2153
2154
_status = rtw_set_802_11_bssid_list_scan(padapter, NULL);
2155
2156
if (_status == _FALSE)
2157
ret = -1;
2158
2159
cancel_ps_deny:
2160
rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
2161
2162
exit:
2163
#ifdef DBG_IOCTL
2164
RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2165
#endif
2166
2167
return ret;
2168
}
2169
2170
static int rtw_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
2171
union iwreq_data *wrqu, char *extra)
2172
{
2173
_irqL irqL;
2174
_list *plist, *phead;
2175
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2176
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2177
RT_CHANNEL_INFO *chset = rfctl->channel_set;
2178
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2179
_queue *queue = &(pmlmepriv->scanned_queue);
2180
struct wlan_network *pnetwork = NULL;
2181
char *ev = extra;
2182
char *stop = ev + wrqu->data.length;
2183
u32 ret = 0;
2184
u32 wait_for_surveydone;
2185
sint wait_status;
2186
u8 ch;
2187
2188
#ifdef CONFIG_P2P
2189
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
2190
#endif /* CONFIG_P2P */
2191
2192
2193
#ifdef DBG_IOCTL
2194
RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2195
#endif
2196
2197
if (adapter_to_pwrctl(padapter)->brfoffbyhw && rtw_is_drv_stopped(padapter)) {
2198
ret = -EINVAL;
2199
goto exit;
2200
}
2201
2202
#ifdef CONFIG_P2P
2203
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2204
wait_for_surveydone = 200;
2205
else {
2206
/* P2P is disabled */
2207
wait_for_surveydone = 100;
2208
}
2209
#else
2210
{
2211
wait_for_surveydone = 100;
2212
}
2213
#endif /* CONFIG_P2P */
2214
2215
#if 1 /* Wireless Extension use EAGAIN to try */
2216
wait_status = _FW_UNDER_SURVEY
2217
#ifndef CONFIG_ANDROID
2218
| _FW_UNDER_LINKING
2219
#endif
2220
;
2221
2222
while (check_fwstate(pmlmepriv, wait_status) == _TRUE)
2223
return -EAGAIN;
2224
#else
2225
wait_status = _FW_UNDER_SURVEY
2226
#ifndef CONFIG_ANDROID
2227
| _FW_UNDER_LINKING
2228
#endif
2229
;
2230
2231
while (check_fwstate(pmlmepriv, wait_status) == _TRUE) {
2232
rtw_msleep_os(30);
2233
cnt++;
2234
if (cnt > wait_for_surveydone)
2235
break;
2236
}
2237
#endif
2238
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2239
2240
phead = get_list_head(queue);
2241
plist = get_next(phead);
2242
2243
while (1) {
2244
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
2245
break;
2246
2247
if ((stop - ev) < SCAN_ITEM_SIZE) {
2248
if(wrqu->data.length == MAX_SCAN_BUFFER_LEN){ /*max buffer len defined by iwlist*/
2249
ret = 0;
2250
RTW_INFO("%s: Scan results incomplete\n", __FUNCTION__);
2251
break;
2252
}
2253
ret = -E2BIG;
2254
break;
2255
}
2256
2257
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2258
ch = pnetwork->network.Configuration.DSConfig;
2259
2260
/* report network only if the current channel set contains the channel to which this network belongs */
2261
if (rtw_chset_search_ch(chset, ch) >= 0
2262
&& rtw_mlme_band_check(padapter, ch) == _TRUE
2263
&& _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2264
&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
2265
|| rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl))
2266
|| !rtw_chset_is_ch_non_ocp(chset, ch))
2267
)
2268
ev = translate_scan(padapter, a, pnetwork, ev, stop);
2269
2270
plist = get_next(plist);
2271
2272
}
2273
2274
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2275
2276
wrqu->data.length = ev - extra;
2277
wrqu->data.flags = 0;
2278
2279
exit:
2280
2281
2282
#ifdef DBG_IOCTL
2283
RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2284
#endif
2285
2286
return ret ;
2287
2288
}
2289
2290
/* set ssid flow
2291
* s1. rtw_set_802_11_infrastructure_mode()
2292
* s2. set_802_11_authenticaion_mode()
2293
* s3. set_802_11_encryption_mode()
2294
* s4. rtw_set_802_11_ssid() */
2295
static int rtw_wx_set_essid(struct net_device *dev,
2296
struct iw_request_info *a,
2297
union iwreq_data *wrqu, char *extra)
2298
{
2299
_irqL irqL;
2300
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2301
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2302
_queue *queue = &pmlmepriv->scanned_queue;
2303
_list *phead;
2304
struct wlan_network *pnetwork = NULL;
2305
NDIS_802_11_AUTHENTICATION_MODE authmode;
2306
NDIS_802_11_SSID ndis_ssid;
2307
u8 *dst_ssid, *src_ssid;
2308
2309
uint ret = 0, len;
2310
2311
2312
#ifdef DBG_IOCTL
2313
RTW_INFO("DBG_IOCTL %s:%d\n", __FUNCTION__, __LINE__);
2314
#endif
2315
#ifdef CONFIG_WEXT_DONT_JOIN_BYSSID
2316
RTW_INFO("%s: CONFIG_WEXT_DONT_JOIN_BYSSID be defined!! only allow bssid joining\n", __func__);
2317
return -EPERM;
2318
#endif
2319
2320
#if WIRELESS_EXT <= 20
2321
if ((wrqu->essid.length - 1) > IW_ESSID_MAX_SIZE) {
2322
#else
2323
if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
2324
#endif
2325
ret = -E2BIG;
2326
goto exit;
2327
}
2328
2329
2330
2331
rtw_ps_deny(padapter, PS_DENY_JOIN);
2332
if (_FAIL == rtw_pwr_wakeup(padapter)) {
2333
ret = -1;
2334
goto cancel_ps_deny;
2335
}
2336
2337
if (!padapter->bup) {
2338
ret = -1;
2339
goto cancel_ps_deny;
2340
}
2341
2342
if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
2343
ret = -1;
2344
goto cancel_ps_deny;
2345
}
2346
2347
#ifdef CONFIG_CONCURRENT_MODE
2348
if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY | _FW_UNDER_LINKING)) {
2349
RTW_INFO("set ssid, but buddy_intf is under scanning or linking\n");
2350
ret = -EINVAL;
2351
goto cancel_ps_deny;
2352
}
2353
#endif
2354
authmode = padapter->securitypriv.ndisauthtype;
2355
RTW_INFO("=>%s\n", __FUNCTION__);
2356
if (wrqu->essid.flags && wrqu->essid.length) {
2357
/* Commented by Albert 20100519 */
2358
/* We got the codes in "set_info" function of iwconfig source code. */
2359
/* ========================================= */
2360
/* wrq.u.essid.length = strlen(essid) + 1; */
2361
/* if(we_kernel_version > 20) */
2362
/* wrq.u.essid.length--; */
2363
/* ========================================= */
2364
/* That means, if the WIRELESS_EXT less than or equal to 20, the correct ssid len should subtract 1. */
2365
#if WIRELESS_EXT <= 20
2366
len = ((wrqu->essid.length - 1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length - 1) : IW_ESSID_MAX_SIZE;
2367
#else
2368
len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : IW_ESSID_MAX_SIZE;
2369
#endif
2370
2371
if (wrqu->essid.length != 33)
2372
RTW_INFO("ssid=%s, len=%d\n", extra, wrqu->essid.length);
2373
2374
_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
2375
ndis_ssid.SsidLength = len;
2376
_rtw_memcpy(ndis_ssid.Ssid, extra, len);
2377
src_ssid = ndis_ssid.Ssid;
2378
2379
_enter_critical_bh(&queue->lock, &irqL);
2380
phead = get_list_head(queue);
2381
pmlmepriv->pscanned = get_next(phead);
2382
2383
while (1) {
2384
if (rtw_end_of_queue_search(phead, pmlmepriv->pscanned) == _TRUE) {
2385
#if 0
2386
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2387
rtw_set_802_11_ssid(padapter, &ndis_ssid);
2388
2389
goto cancel_ps_deny;
2390
} else {
2391
ret = -EINVAL;
2392
goto cancel_ps_deny;
2393
}
2394
#endif
2395
2396
break;
2397
}
2398
2399
pnetwork = LIST_CONTAINOR(pmlmepriv->pscanned, struct wlan_network, list);
2400
2401
pmlmepriv->pscanned = get_next(pmlmepriv->pscanned);
2402
2403
dst_ssid = pnetwork->network.Ssid.Ssid;
2404
2405
2406
if ((_rtw_memcmp(dst_ssid, src_ssid, ndis_ssid.SsidLength) == _TRUE) &&
2407
(pnetwork->network.Ssid.SsidLength == ndis_ssid.SsidLength)) {
2408
2409
if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) {
2410
if (pnetwork->network.InfrastructureMode != pmlmepriv->cur_network.network.InfrastructureMode)
2411
continue;
2412
}
2413
2414
if (rtw_set_802_11_infrastructure_mode(padapter, pnetwork->network.InfrastructureMode, 0) == _FALSE) {
2415
ret = -1;
2416
_exit_critical_bh(&queue->lock, &irqL);
2417
goto cancel_ps_deny;
2418
}
2419
2420
break;
2421
}
2422
}
2423
_exit_critical_bh(&queue->lock, &irqL);
2424
rtw_set_802_11_authentication_mode(padapter, authmode);
2425
/* set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
2426
if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
2427
ret = -1;
2428
goto cancel_ps_deny;
2429
}
2430
}
2431
2432
cancel_ps_deny:
2433
rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
2434
2435
exit:
2436
RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
2437
2438
#ifdef DBG_IOCTL
2439
RTW_INFO("DBG_IOCTL %s:%d return %d\n", __FUNCTION__, __LINE__, ret);
2440
#endif
2441
2442
2443
return ret;
2444
}
2445
2446
static int rtw_wx_get_essid(struct net_device *dev,
2447
struct iw_request_info *a,
2448
union iwreq_data *wrqu, char *extra)
2449
{
2450
u32 len, ret = 0;
2451
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2452
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2453
WLAN_BSSID_EX *pcur_bss = &pmlmepriv->cur_network.network;
2454
2455
2456
2457
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) ||
2458
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
2459
len = pcur_bss->Ssid.SsidLength;
2460
2461
wrqu->essid.length = len;
2462
2463
_rtw_memcpy(extra, pcur_bss->Ssid.Ssid, len);
2464
2465
wrqu->essid.flags = 1;
2466
} else {
2467
ret = -1;
2468
goto exit;
2469
}
2470
2471
exit:
2472
2473
2474
return ret;
2475
2476
}
2477
2478
static int rtw_wx_set_rate(struct net_device *dev,
2479
struct iw_request_info *a,
2480
union iwreq_data *wrqu, char *extra)
2481
{
2482
int i, ret = 0;
2483
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2484
u8 datarates[NumRates];
2485
u32 target_rate = wrqu->bitrate.value;
2486
u32 fixed = wrqu->bitrate.fixed;
2487
u32 ratevalue = 0;
2488
u8 mpdatarate[NumRates] = {11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 0xff};
2489
2490
2491
2492
if (target_rate == -1) {
2493
ratevalue = 11;
2494
goto set_rate;
2495
}
2496
target_rate = target_rate / 100000;
2497
2498
switch (target_rate) {
2499
case 10:
2500
ratevalue = 0;
2501
break;
2502
case 20:
2503
ratevalue = 1;
2504
break;
2505
case 55:
2506
ratevalue = 2;
2507
break;
2508
case 60:
2509
ratevalue = 3;
2510
break;
2511
case 90:
2512
ratevalue = 4;
2513
break;
2514
case 110:
2515
ratevalue = 5;
2516
break;
2517
case 120:
2518
ratevalue = 6;
2519
break;
2520
case 180:
2521
ratevalue = 7;
2522
break;
2523
case 240:
2524
ratevalue = 8;
2525
break;
2526
case 360:
2527
ratevalue = 9;
2528
break;
2529
case 480:
2530
ratevalue = 10;
2531
break;
2532
case 540:
2533
ratevalue = 11;
2534
break;
2535
default:
2536
ratevalue = 11;
2537
break;
2538
}
2539
2540
set_rate:
2541
2542
for (i = 0; i < NumRates; i++) {
2543
if (ratevalue == mpdatarate[i]) {
2544
datarates[i] = mpdatarate[i];
2545
if (fixed == 0)
2546
break;
2547
} else
2548
datarates[i] = 0xff;
2549
2550
}
2551
2552
if (rtw_setdatarate_cmd(padapter, datarates) != _SUCCESS) {
2553
ret = -1;
2554
}
2555
2556
2557
return ret;
2558
}
2559
2560
static int rtw_wx_get_rate(struct net_device *dev,
2561
struct iw_request_info *info,
2562
union iwreq_data *wrqu, char *extra)
2563
{
2564
u16 max_rate = 0;
2565
2566
max_rate = rtw_get_cur_max_rate((_adapter *)rtw_netdev_priv(dev));
2567
2568
if (max_rate == 0)
2569
return -EPERM;
2570
2571
wrqu->bitrate.fixed = 0; /* no auto select */
2572
wrqu->bitrate.value = max_rate * 100000;
2573
2574
return 0;
2575
}
2576
2577
static int rtw_wx_set_rts(struct net_device *dev,
2578
struct iw_request_info *info,
2579
union iwreq_data *wrqu, char *extra)
2580
{
2581
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2582
2583
2584
if (wrqu->rts.disabled)
2585
padapter->registrypriv.rts_thresh = 2347;
2586
else {
2587
if (wrqu->rts.value < 0 ||
2588
wrqu->rts.value > 2347)
2589
return -EINVAL;
2590
2591
padapter->registrypriv.rts_thresh = wrqu->rts.value;
2592
}
2593
2594
RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2595
2596
2597
return 0;
2598
2599
}
2600
2601
static int rtw_wx_get_rts(struct net_device *dev,
2602
struct iw_request_info *info,
2603
union iwreq_data *wrqu, char *extra)
2604
{
2605
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2606
2607
2608
RTW_INFO("%s, rts_thresh=%d\n", __func__, padapter->registrypriv.rts_thresh);
2609
2610
wrqu->rts.value = padapter->registrypriv.rts_thresh;
2611
wrqu->rts.fixed = 0; /* no auto select */
2612
/* wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); */
2613
2614
2615
return 0;
2616
}
2617
2618
static int rtw_wx_set_frag(struct net_device *dev,
2619
struct iw_request_info *info,
2620
union iwreq_data *wrqu, char *extra)
2621
{
2622
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2623
2624
2625
if (wrqu->frag.disabled)
2626
padapter->xmitpriv.frag_len = MAX_FRAG_THRESHOLD;
2627
else {
2628
if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
2629
wrqu->frag.value > MAX_FRAG_THRESHOLD)
2630
return -EINVAL;
2631
2632
padapter->xmitpriv.frag_len = wrqu->frag.value & ~0x1;
2633
}
2634
2635
RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2636
2637
2638
return 0;
2639
2640
}
2641
2642
static int rtw_wx_get_frag(struct net_device *dev,
2643
struct iw_request_info *info,
2644
union iwreq_data *wrqu, char *extra)
2645
{
2646
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2647
2648
2649
RTW_INFO("%s, frag_len=%d\n", __func__, padapter->xmitpriv.frag_len);
2650
2651
wrqu->frag.value = padapter->xmitpriv.frag_len;
2652
wrqu->frag.fixed = 0; /* no auto select */
2653
/* wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); */
2654
2655
2656
return 0;
2657
}
2658
2659
static int rtw_wx_get_retry(struct net_device *dev,
2660
struct iw_request_info *info,
2661
union iwreq_data *wrqu, char *extra)
2662
{
2663
/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
2664
2665
2666
wrqu->retry.value = 7;
2667
wrqu->retry.fixed = 0; /* no auto select */
2668
wrqu->retry.disabled = 1;
2669
2670
return 0;
2671
2672
}
2673
2674
#if 0
2675
#define IW_ENCODE_INDEX 0x00FF /* Token index (if needed) */
2676
#define IW_ENCODE_FLAGS 0xFF00 /* Flags defined below */
2677
#define IW_ENCODE_MODE 0xF000 /* Modes defined below */
2678
#define IW_ENCODE_DISABLED 0x8000 /* Encoding disabled */
2679
#define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
2680
#define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
2681
#define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
2682
#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
2683
#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
2684
/*
2685
iwconfig wlan0 key on->flags = 0x6001->maybe it means auto
2686
iwconfig wlan0 key off->flags = 0x8800
2687
iwconfig wlan0 key open->flags = 0x2800
2688
iwconfig wlan0 key open 1234567890->flags = 0x2000
2689
iwconfig wlan0 key restricted->flags = 0x4800
2690
iwconfig wlan0 key open [3] 1234567890->flags = 0x2003
2691
iwconfig wlan0 key restricted [2] 1234567890->flags = 0x4002
2692
iwconfig wlan0 key open [3] -> flags = 0x2803
2693
iwconfig wlan0 key restricted [2] -> flags = 0x4802
2694
*/
2695
#endif
2696
2697
static int rtw_wx_set_enc(struct net_device *dev,
2698
struct iw_request_info *info,
2699
union iwreq_data *wrqu, char *keybuf)
2700
{
2701
u32 key, ret = 0;
2702
u32 keyindex_provided;
2703
NDIS_802_11_WEP wep;
2704
NDIS_802_11_AUTHENTICATION_MODE authmode;
2705
2706
struct iw_point *erq = &(wrqu->encoding);
2707
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2708
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
2709
RTW_INFO("+rtw_wx_set_enc, flags=0x%x\n", erq->flags);
2710
2711
_rtw_memset(&wep, 0, sizeof(NDIS_802_11_WEP));
2712
2713
key = erq->flags & IW_ENCODE_INDEX;
2714
2715
2716
if (erq->flags & IW_ENCODE_DISABLED) {
2717
RTW_INFO("EncryptionDisabled\n");
2718
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
2719
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2720
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2721
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2722
authmode = Ndis802_11AuthModeOpen;
2723
padapter->securitypriv.ndisauthtype = authmode;
2724
2725
goto exit;
2726
}
2727
2728
if (key) {
2729
if (key > WEP_KEYS)
2730
return -EINVAL;
2731
key--;
2732
keyindex_provided = 1;
2733
} else {
2734
keyindex_provided = 0;
2735
key = padapter->securitypriv.dot11PrivacyKeyIndex;
2736
RTW_INFO("rtw_wx_set_enc, key=%d\n", key);
2737
}
2738
2739
/* set authentication mode */
2740
if (erq->flags & IW_ENCODE_OPEN) {
2741
RTW_INFO("rtw_wx_set_enc():IW_ENCODE_OPEN\n");
2742
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
2743
2744
#ifdef CONFIG_PLATFORM_MT53XX
2745
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2746
#else
2747
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
2748
#endif
2749
2750
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2751
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2752
authmode = Ndis802_11AuthModeOpen;
2753
padapter->securitypriv.ndisauthtype = authmode;
2754
} else if (erq->flags & IW_ENCODE_RESTRICTED) {
2755
RTW_INFO("rtw_wx_set_enc():IW_ENCODE_RESTRICTED\n");
2756
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
2757
2758
#ifdef CONFIG_PLATFORM_MT53XX
2759
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
2760
#else
2761
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
2762
#endif
2763
2764
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2765
padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
2766
authmode = Ndis802_11AuthModeShared;
2767
padapter->securitypriv.ndisauthtype = authmode;
2768
} else {
2769
RTW_INFO("rtw_wx_set_enc():erq->flags=0x%x\n", erq->flags);
2770
2771
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;/* Ndis802_11EncryptionDisabled; */
2772
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
2773
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2774
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
2775
authmode = Ndis802_11AuthModeOpen;
2776
padapter->securitypriv.ndisauthtype = authmode;
2777
}
2778
2779
wep.KeyIndex = key;
2780
if (erq->length > 0) {
2781
wep.KeyLength = erq->length <= 5 ? 5 : 13;
2782
2783
wep.Length = wep.KeyLength + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
2784
} else {
2785
wep.KeyLength = 0 ;
2786
2787
if (keyindex_provided == 1) { /* set key_id only, no given KeyMaterial(erq->length==0). */
2788
padapter->securitypriv.dot11PrivacyKeyIndex = key;
2789
2790
RTW_INFO("(keyindex_provided == 1), keyid=%d, key_len=%d\n", key, padapter->securitypriv.dot11DefKeylen[key]);
2791
2792
switch (padapter->securitypriv.dot11DefKeylen[key]) {
2793
case 5:
2794
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
2795
break;
2796
case 13:
2797
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
2798
break;
2799
default:
2800
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
2801
break;
2802
}
2803
2804
goto exit;
2805
2806
}
2807
2808
}
2809
2810
wep.KeyIndex |= 0x80000000;
2811
2812
_rtw_memcpy(wep.KeyMaterial, keybuf, wep.KeyLength);
2813
2814
if (rtw_set_802_11_add_wep(padapter, &wep) == _FALSE) {
2815
if (rf_on == pwrpriv->rf_pwrstate)
2816
ret = -EOPNOTSUPP;
2817
goto exit;
2818
}
2819
2820
exit:
2821
2822
2823
return ret;
2824
2825
}
2826
2827
static int rtw_wx_get_enc(struct net_device *dev,
2828
struct iw_request_info *info,
2829
union iwreq_data *wrqu, char *keybuf)
2830
{
2831
uint key, ret = 0;
2832
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2833
struct iw_point *erq = &(wrqu->encoding);
2834
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2835
2836
2837
if (check_fwstate(pmlmepriv, _FW_LINKED) != _TRUE) {
2838
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) != _TRUE) {
2839
erq->length = 0;
2840
erq->flags |= IW_ENCODE_DISABLED;
2841
return 0;
2842
}
2843
}
2844
2845
2846
key = erq->flags & IW_ENCODE_INDEX;
2847
2848
if (key) {
2849
if (key > WEP_KEYS)
2850
return -EINVAL;
2851
key--;
2852
} else
2853
key = padapter->securitypriv.dot11PrivacyKeyIndex;
2854
2855
erq->flags = key + 1;
2856
2857
/* if(padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen) */
2858
/* { */
2859
/* erq->flags |= IW_ENCODE_OPEN; */
2860
/* } */
2861
2862
switch (padapter->securitypriv.ndisencryptstatus) {
2863
case Ndis802_11EncryptionNotSupported:
2864
case Ndis802_11EncryptionDisabled:
2865
2866
erq->length = 0;
2867
erq->flags |= IW_ENCODE_DISABLED;
2868
2869
break;
2870
2871
case Ndis802_11Encryption1Enabled:
2872
2873
erq->length = padapter->securitypriv.dot11DefKeylen[key];
2874
2875
if (erq->length) {
2876
_rtw_memcpy(keybuf, padapter->securitypriv.dot11DefKey[key].skey, padapter->securitypriv.dot11DefKeylen[key]);
2877
2878
erq->flags |= IW_ENCODE_ENABLED;
2879
2880
if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeOpen)
2881
erq->flags |= IW_ENCODE_OPEN;
2882
else if (padapter->securitypriv.ndisauthtype == Ndis802_11AuthModeShared)
2883
erq->flags |= IW_ENCODE_RESTRICTED;
2884
} else {
2885
erq->length = 0;
2886
erq->flags |= IW_ENCODE_DISABLED;
2887
}
2888
2889
break;
2890
2891
case Ndis802_11Encryption2Enabled:
2892
case Ndis802_11Encryption3Enabled:
2893
2894
erq->length = 16;
2895
erq->flags |= (IW_ENCODE_ENABLED | IW_ENCODE_OPEN | IW_ENCODE_NOKEY);
2896
2897
break;
2898
2899
default:
2900
erq->length = 0;
2901
erq->flags |= IW_ENCODE_DISABLED;
2902
2903
break;
2904
2905
}
2906
2907
2908
return ret;
2909
2910
}
2911
2912
static int rtw_wx_get_power(struct net_device *dev,
2913
struct iw_request_info *info,
2914
union iwreq_data *wrqu, char *extra)
2915
{
2916
/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
2917
2918
wrqu->power.value = 0;
2919
wrqu->power.fixed = 0; /* no auto select */
2920
wrqu->power.disabled = 1;
2921
2922
return 0;
2923
2924
}
2925
2926
static int rtw_wx_set_gen_ie(struct net_device *dev,
2927
struct iw_request_info *info,
2928
union iwreq_data *wrqu, char *extra)
2929
{
2930
int ret;
2931
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2932
2933
ret = rtw_set_wpa_ie(padapter, extra, wrqu->data.length);
2934
2935
return ret;
2936
}
2937
2938
static int rtw_wx_set_auth(struct net_device *dev,
2939
struct iw_request_info *info,
2940
union iwreq_data *wrqu, char *extra)
2941
{
2942
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
2943
struct iw_param *param = (struct iw_param *)&(wrqu->param);
2944
#ifdef CONFIG_WAPI_SUPPORT
2945
#ifndef CONFIG_IOCTL_CFG80211
2946
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2947
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2948
struct security_priv *psecuritypriv = &padapter->securitypriv;
2949
u32 value = param->value;
2950
#endif
2951
#endif
2952
int ret = 0;
2953
2954
switch (param->flags & IW_AUTH_INDEX) {
2955
2956
case IW_AUTH_WPA_VERSION:
2957
#ifdef CONFIG_WAPI_SUPPORT
2958
#ifndef CONFIG_IOCTL_CFG80211
2959
padapter->wapiInfo.bWapiEnable = false;
2960
if (value == IW_AUTH_WAPI_VERSION_1) {
2961
padapter->wapiInfo.bWapiEnable = true;
2962
psecuritypriv->dot11PrivacyAlgrthm = _SMS4_;
2963
psecuritypriv->dot118021XGrpPrivacy = _SMS4_;
2964
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
2965
pmlmeinfo->auth_algo = psecuritypriv->dot11AuthAlgrthm;
2966
padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
2967
padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
2968
}
2969
#endif
2970
#endif
2971
break;
2972
case IW_AUTH_CIPHER_PAIRWISE:
2973
2974
break;
2975
case IW_AUTH_CIPHER_GROUP:
2976
2977
break;
2978
case IW_AUTH_KEY_MGMT:
2979
#ifdef CONFIG_WAPI_SUPPORT
2980
#ifndef CONFIG_IOCTL_CFG80211
2981
RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT case\n");
2982
if (value == IW_AUTH_KEY_MGMT_WAPI_PSK)
2983
padapter->wapiInfo.bWapiPSK = true;
2984
else
2985
padapter->wapiInfo.bWapiPSK = false;
2986
RTW_INFO("rtw_wx_set_auth: IW_AUTH_KEY_MGMT bwapipsk %d\n", padapter->wapiInfo.bWapiPSK);
2987
#endif
2988
#endif
2989
/*
2990
* ??? does not use these parameters
2991
*/
2992
break;
2993
2994
case IW_AUTH_TKIP_COUNTERMEASURES: {
2995
if (param->value) {
2996
/* wpa_supplicant is enabling the tkip countermeasure. */
2997
padapter->securitypriv.btkip_countermeasure = _TRUE;
2998
} else {
2999
/* wpa_supplicant is disabling the tkip countermeasure. */
3000
padapter->securitypriv.btkip_countermeasure = _FALSE;
3001
}
3002
break;
3003
}
3004
case IW_AUTH_DROP_UNENCRYPTED: {
3005
/* HACK:
3006
*
3007
* wpa_supplicant calls set_wpa_enabled when the driver
3008
* is loaded and unloaded, regardless of if WPA is being
3009
* used. No other calls are made which can be used to
3010
* determine if encryption will be used or not prior to
3011
* association being expected. If encryption is not being
3012
* used, drop_unencrypted is set to false, else true -- we
3013
* can use this to determine if the CAP_PRIVACY_ON bit should
3014
* be set.
3015
*/
3016
3017
if (padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption1Enabled) {
3018
break;/* it means init value, or using wep, ndisencryptstatus = Ndis802_11Encryption1Enabled, */
3019
/* then it needn't reset it; */
3020
}
3021
3022
if (param->value) {
3023
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3024
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3025
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3026
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3027
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeOpen;
3028
}
3029
3030
break;
3031
}
3032
3033
case IW_AUTH_80211_AUTH_ALG:
3034
3035
#if defined(CONFIG_ANDROID) || 1
3036
/*
3037
* It's the starting point of a link layer connection using wpa_supplicant
3038
*/
3039
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3040
LeaveAllPowerSaveMode(padapter);
3041
rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK);
3042
RTW_INFO("%s...call rtw_indicate_disconnect\n ", __FUNCTION__);
3043
rtw_indicate_disconnect(padapter, 0, _FALSE);
3044
rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK);
3045
}
3046
#endif
3047
3048
3049
ret = wpa_set_auth_algs(dev, (u32)param->value);
3050
3051
break;
3052
3053
case IW_AUTH_WPA_ENABLED:
3054
3055
/* if(param->value) */
3056
/* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; */ /* 802.1x */
3057
/* else */
3058
/* padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_Open; */ /* open system */
3059
3060
/* _disassociate(priv); */
3061
3062
break;
3063
3064
case IW_AUTH_RX_UNENCRYPTED_EAPOL:
3065
/* ieee->ieee802_1x = param->value; */
3066
break;
3067
3068
case IW_AUTH_PRIVACY_INVOKED:
3069
/* ieee->privacy_invoked = param->value; */
3070
break;
3071
3072
#ifdef CONFIG_WAPI_SUPPORT
3073
#ifndef CONFIG_IOCTL_CFG80211
3074
case IW_AUTH_WAPI_ENABLED:
3075
break;
3076
#endif
3077
#endif
3078
3079
default:
3080
return -EOPNOTSUPP;
3081
3082
}
3083
3084
return ret;
3085
3086
}
3087
3088
static int rtw_wx_set_enc_ext(struct net_device *dev,
3089
struct iw_request_info *info,
3090
union iwreq_data *wrqu, char *extra)
3091
{
3092
char *alg_name;
3093
u32 param_len;
3094
struct ieee_param *param = NULL;
3095
struct iw_point *pencoding = &wrqu->encoding;
3096
struct iw_encode_ext *pext = (struct iw_encode_ext *)extra;
3097
int ret = 0;
3098
3099
param_len = sizeof(struct ieee_param) + pext->key_len;
3100
param = (struct ieee_param *)rtw_malloc(param_len);
3101
if (param == NULL)
3102
return -1;
3103
3104
_rtw_memset(param, 0, param_len);
3105
3106
param->cmd = IEEE_CMD_SET_ENCRYPTION;
3107
_rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
3108
3109
3110
switch (pext->alg) {
3111
case IW_ENCODE_ALG_NONE:
3112
/* todo: remove key */
3113
/* remove = 1; */
3114
alg_name = "none";
3115
break;
3116
case IW_ENCODE_ALG_WEP:
3117
alg_name = "WEP";
3118
break;
3119
case IW_ENCODE_ALG_TKIP:
3120
alg_name = "TKIP";
3121
break;
3122
case IW_ENCODE_ALG_CCMP:
3123
alg_name = "CCMP";
3124
break;
3125
#ifdef CONFIG_IEEE80211W
3126
case IW_ENCODE_ALG_AES_CMAC:
3127
alg_name = "BIP";
3128
break;
3129
#endif /* CONFIG_IEEE80211W */
3130
#ifdef CONFIG_WAPI_SUPPORT
3131
#ifndef CONFIG_IOCTL_CFG80211
3132
case IW_ENCODE_ALG_SM4:
3133
alg_name = "SMS4";
3134
_rtw_memcpy(param->sta_addr, pext->addr.sa_data, ETH_ALEN);
3135
RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
3136
break;
3137
#endif
3138
#endif
3139
default:
3140
ret = -1;
3141
goto exit;
3142
}
3143
3144
strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
3145
3146
if (pext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
3147
param->u.crypt.set_tx = 1;
3148
3149
/* cliW: WEP does not have group key
3150
* just not checking GROUP key setting
3151
*/
3152
if ((pext->alg != IW_ENCODE_ALG_WEP) &&
3153
((pext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
3154
#ifdef CONFIG_IEEE80211W
3155
|| (pext->ext_flags & IW_ENCODE_ALG_AES_CMAC)
3156
#endif /* CONFIG_IEEE80211W */
3157
))
3158
param->u.crypt.set_tx = 0;
3159
3160
param->u.crypt.idx = (pencoding->flags & 0x00FF) - 1 ;
3161
3162
if (pext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) {
3163
#ifdef CONFIG_WAPI_SUPPORT
3164
#ifndef CONFIG_IOCTL_CFG80211
3165
if (pext->alg == IW_ENCODE_ALG_SM4)
3166
_rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 16);
3167
else
3168
#endif /* CONFIG_IOCTL_CFG80211 */
3169
#endif /* CONFIG_WAPI_SUPPORT */
3170
_rtw_memcpy(param->u.crypt.seq, pext->rx_seq, 8);
3171
}
3172
3173
if (pext->key_len) {
3174
param->u.crypt.key_len = pext->key_len;
3175
/* _rtw_memcpy(param + 1, pext + 1, pext->key_len); */
3176
_rtw_memcpy(param->u.crypt.key, pext + 1, pext->key_len);
3177
}
3178
3179
if (pencoding->flags & IW_ENCODE_DISABLED) {
3180
/* todo: remove key */
3181
/* remove = 1; */
3182
}
3183
3184
ret = wpa_set_encryption(dev, param, param_len);
3185
3186
exit:
3187
if (param)
3188
rtw_mfree((u8 *)param, param_len);
3189
3190
return ret;
3191
}
3192
3193
3194
static int rtw_wx_get_nick(struct net_device *dev,
3195
struct iw_request_info *info,
3196
union iwreq_data *wrqu, char *extra)
3197
{
3198
/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3199
/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3200
/* struct security_priv *psecuritypriv = &padapter->securitypriv; */
3201
3202
if (extra) {
3203
wrqu->data.length = 14;
3204
wrqu->data.flags = 1;
3205
_rtw_memcpy(extra, "WIFI@RTL8814AU", 14);
3206
}
3207
3208
/* rtw_signal_process(pid, SIGUSR1); */ /* for test */
3209
3210
/* dump debug info here */
3211
#if 0
3212
u32 dot11AuthAlgrthm; /* 802.11 auth, could be open, shared, and 8021x */
3213
u32 dot11PrivacyAlgrthm; /* This specify the privacy for shared auth. algorithm. */
3214
u32 dot118021XGrpPrivacy; /* This specify the privacy algthm. used for Grp key */
3215
u32 ndisauthtype;
3216
u32 ndisencryptstatus;
3217
#endif
3218
3219
/* RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n", */
3220
/* psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm, */
3221
/* psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus); */
3222
3223
/* RTW_INFO("enc_alg=0x%x\n", psecuritypriv->dot11PrivacyAlgrthm); */
3224
/* RTW_INFO("auth_type=0x%x\n", psecuritypriv->ndisauthtype); */
3225
/* RTW_INFO("enc_type=0x%x\n", psecuritypriv->ndisencryptstatus); */
3226
3227
#if 0
3228
RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
3229
RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
3230
RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
3231
RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
3232
RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
3233
3234
RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
3235
3236
3237
RTW_INFO("\n");
3238
3239
RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
3240
RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
3241
3242
RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
3243
3244
RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
3245
3246
RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
3247
RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
3248
3249
RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
3250
RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
3251
RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
3252
RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
3253
#endif
3254
3255
return 0;
3256
3257
}
3258
3259
static int rtw_wx_read32(struct net_device *dev,
3260
struct iw_request_info *info,
3261
union iwreq_data *wrqu, char *extra)
3262
{
3263
PADAPTER padapter;
3264
struct iw_point *p;
3265
u16 len;
3266
u32 addr;
3267
u32 data32;
3268
u32 bytes;
3269
u8 *ptmp;
3270
int ret;
3271
3272
3273
ret = 0;
3274
padapter = (PADAPTER)rtw_netdev_priv(dev);
3275
p = &wrqu->data;
3276
len = p->length;
3277
if (0 == len)
3278
return -EINVAL;
3279
3280
ptmp = (u8 *)rtw_malloc(len);
3281
if (NULL == ptmp)
3282
return -ENOMEM;
3283
3284
if (copy_from_user(ptmp, p->pointer, len)) {
3285
ret = -EFAULT;
3286
goto exit;
3287
}
3288
3289
bytes = 0;
3290
addr = 0;
3291
sscanf(ptmp, "%d,%x", &bytes, &addr);
3292
3293
switch (bytes) {
3294
case 1:
3295
data32 = rtw_read8(padapter, addr);
3296
sprintf(extra, "0x%02X", data32);
3297
break;
3298
case 2:
3299
data32 = rtw_read16(padapter, addr);
3300
sprintf(extra, "0x%04X", data32);
3301
break;
3302
case 4:
3303
data32 = rtw_read32(padapter, addr);
3304
sprintf(extra, "0x%08X", data32);
3305
break;
3306
3307
#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)
3308
case 11:
3309
data32 = rtw_sd_iread8(padapter, addr);
3310
sprintf(extra, "0x%02X", data32);
3311
break;
3312
case 12:
3313
data32 = rtw_sd_iread16(padapter, addr);
3314
sprintf(extra, "0x%04X", data32);
3315
break;
3316
case 14:
3317
data32 = rtw_sd_iread32(padapter, addr);
3318
sprintf(extra, "0x%08X", data32);
3319
break;
3320
#endif
3321
default:
3322
RTW_INFO("%s: usage> read [bytes],[address(hex)]\n", __func__);
3323
ret = -EINVAL;
3324
goto exit;
3325
}
3326
RTW_INFO("%s: addr=0x%08X data=%s\n", __func__, addr, extra);
3327
3328
exit:
3329
rtw_mfree(ptmp, len);
3330
3331
return 0;
3332
}
3333
3334
static int rtw_wx_write32(struct net_device *dev,
3335
struct iw_request_info *info,
3336
union iwreq_data *wrqu, char *extra)
3337
{
3338
PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3339
3340
u32 addr;
3341
u32 data32;
3342
u32 bytes;
3343
3344
3345
bytes = 0;
3346
addr = 0;
3347
data32 = 0;
3348
sscanf(extra, "%d,%x,%x", &bytes, &addr, &data32);
3349
3350
switch (bytes) {
3351
case 1:
3352
rtw_write8(padapter, addr, (u8)data32);
3353
RTW_INFO("%s: addr=0x%08X data=0x%02X\n", __func__, addr, (u8)data32);
3354
break;
3355
case 2:
3356
rtw_write16(padapter, addr, (u16)data32);
3357
RTW_INFO("%s: addr=0x%08X data=0x%04X\n", __func__, addr, (u16)data32);
3358
break;
3359
case 4:
3360
rtw_write32(padapter, addr, data32);
3361
RTW_INFO("%s: addr=0x%08X data=0x%08X\n", __func__, addr, data32);
3362
break;
3363
default:
3364
RTW_INFO("%s: usage> write [bytes],[address(hex)],[data(hex)]\n", __func__);
3365
return -EINVAL;
3366
}
3367
3368
return 0;
3369
}
3370
3371
static int rtw_wx_read_rf(struct net_device *dev,
3372
struct iw_request_info *info,
3373
union iwreq_data *wrqu, char *extra)
3374
{
3375
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3376
u32 path, addr, data32;
3377
3378
3379
path = *(u32 *)extra;
3380
addr = *((u32 *)extra + 1);
3381
data32 = rtw_hal_read_rfreg(padapter, path, addr, 0xFFFFF);
3382
/* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3383
/*
3384
* IMPORTANT!!
3385
* Only when wireless private ioctl is at odd order,
3386
* "extra" would be copied to user space.
3387
*/
3388
sprintf(extra, "0x%05x", data32);
3389
3390
return 0;
3391
}
3392
3393
static int rtw_wx_write_rf(struct net_device *dev,
3394
struct iw_request_info *info,
3395
union iwreq_data *wrqu, char *extra)
3396
{
3397
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3398
u32 path, addr, data32;
3399
3400
3401
path = *(u32 *)extra;
3402
addr = *((u32 *)extra + 1);
3403
data32 = *((u32 *)extra + 2);
3404
/* RTW_INFO("%s: path=%d addr=0x%02x data=0x%05x\n", __func__, path, addr, data32); */
3405
rtw_hal_write_rfreg(padapter, path, addr, 0xFFFFF, data32);
3406
3407
return 0;
3408
}
3409
3410
static int rtw_wx_priv_null(struct net_device *dev, struct iw_request_info *a,
3411
union iwreq_data *wrqu, char *b)
3412
{
3413
return -1;
3414
}
3415
3416
#ifdef CONFIG_RTW_80211K
3417
extern void rm_dbg_cmd(_adapter *padapter, char *s);
3418
static int rtw_wx_priv_rrm(struct net_device *dev, struct iw_request_info *a,
3419
union iwreq_data *wrqu, char *b)
3420
{
3421
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3422
u32 path, addr, data32;
3423
3424
3425
rm_dbg_cmd(padapter, b);
3426
wrqu->data.length = strlen(b);
3427
3428
return 0;
3429
}
3430
#endif
3431
3432
static int dummy(struct net_device *dev, struct iw_request_info *a,
3433
union iwreq_data *wrqu, char *b)
3434
{
3435
/* _adapter *padapter = (_adapter *)rtw_netdev_priv(dev); */
3436
/* struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); */
3437
3438
/* RTW_INFO("cmd_code=%x, fwstate=0x%x\n", a->cmd, get_fwstate(pmlmepriv)); */
3439
3440
return -1;
3441
3442
}
3443
3444
static int rtw_wx_set_channel_plan(struct net_device *dev,
3445
struct iw_request_info *info,
3446
union iwreq_data *wrqu, char *extra)
3447
{
3448
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3449
u8 channel_plan_req = (u8)(*((int *)wrqu));
3450
3451
if (_SUCCESS != rtw_set_channel_plan(padapter, channel_plan_req))
3452
return -EPERM;
3453
3454
return 0;
3455
}
3456
3457
static int rtw_wx_set_mtk_wps_probe_ie(struct net_device *dev,
3458
struct iw_request_info *a,
3459
union iwreq_data *wrqu, char *b)
3460
{
3461
#ifdef CONFIG_PLATFORM_MT53XX
3462
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3463
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3464
3465
#endif
3466
return 0;
3467
}
3468
3469
static int rtw_wx_get_sensitivity(struct net_device *dev,
3470
struct iw_request_info *info,
3471
union iwreq_data *wrqu, char *buf)
3472
{
3473
#ifdef CONFIG_PLATFORM_MT53XX
3474
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3475
3476
/* Modified by Albert 20110914 */
3477
/* This is in dbm format for MTK platform. */
3478
wrqu->qual.level = padapter->recvpriv.rssi;
3479
RTW_INFO(" level = %u\n", wrqu->qual.level);
3480
#endif
3481
return 0;
3482
}
3483
3484
static int rtw_wx_set_mtk_wps_ie(struct net_device *dev,
3485
struct iw_request_info *info,
3486
union iwreq_data *wrqu, char *extra)
3487
{
3488
#ifdef CONFIG_PLATFORM_MT53XX
3489
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3490
3491
return rtw_set_wpa_ie(padapter, wrqu->data.pointer, wrqu->data.length);
3492
#else
3493
return 0;
3494
#endif
3495
}
3496
3497
#ifdef MP_IOCTL_HDL
3498
static void rtw_dbg_mode_hdl(_adapter *padapter, u32 id, u8 *pdata, u32 len)
3499
{
3500
pRW_Reg RegRWStruct;
3501
struct rf_reg_param *prfreg;
3502
u8 path;
3503
u8 offset;
3504
u32 value;
3505
3506
RTW_INFO("%s\n", __FUNCTION__);
3507
3508
switch (id) {
3509
case GEN_MP_IOCTL_SUBCODE(MP_START):
3510
RTW_INFO("871x_driver is only for normal mode, can't enter mp mode\n");
3511
break;
3512
case GEN_MP_IOCTL_SUBCODE(READ_REG):
3513
RegRWStruct = (pRW_Reg)pdata;
3514
switch (RegRWStruct->width) {
3515
case 1:
3516
RegRWStruct->value = rtw_read8(padapter, RegRWStruct->offset);
3517
break;
3518
case 2:
3519
RegRWStruct->value = rtw_read16(padapter, RegRWStruct->offset);
3520
break;
3521
case 4:
3522
RegRWStruct->value = rtw_read32(padapter, RegRWStruct->offset);
3523
break;
3524
default:
3525
break;
3526
}
3527
3528
break;
3529
case GEN_MP_IOCTL_SUBCODE(WRITE_REG):
3530
RegRWStruct = (pRW_Reg)pdata;
3531
switch (RegRWStruct->width) {
3532
case 1:
3533
rtw_write8(padapter, RegRWStruct->offset, (u8)RegRWStruct->value);
3534
break;
3535
case 2:
3536
rtw_write16(padapter, RegRWStruct->offset, (u16)RegRWStruct->value);
3537
break;
3538
case 4:
3539
rtw_write32(padapter, RegRWStruct->offset, (u32)RegRWStruct->value);
3540
break;
3541
default:
3542
break;
3543
}
3544
3545
break;
3546
case GEN_MP_IOCTL_SUBCODE(READ_RF_REG):
3547
3548
prfreg = (struct rf_reg_param *)pdata;
3549
3550
path = (u8)prfreg->path;
3551
offset = (u8)prfreg->offset;
3552
3553
value = rtw_hal_read_rfreg(padapter, path, offset, 0xffffffff);
3554
3555
prfreg->value = value;
3556
3557
break;
3558
case GEN_MP_IOCTL_SUBCODE(WRITE_RF_REG):
3559
3560
prfreg = (struct rf_reg_param *)pdata;
3561
3562
path = (u8)prfreg->path;
3563
offset = (u8)prfreg->offset;
3564
value = prfreg->value;
3565
3566
rtw_hal_write_rfreg(padapter, path, offset, 0xffffffff, value);
3567
3568
break;
3569
case GEN_MP_IOCTL_SUBCODE(TRIGGER_GPIO):
3570
RTW_INFO("==> trigger gpio 0\n");
3571
rtw_hal_set_hwreg(padapter, HW_VAR_TRIGGER_GPIO_0, 0);
3572
break;
3573
#ifdef CONFIG_BT_COEXIST
3574
case GEN_MP_IOCTL_SUBCODE(SET_DM_BT):
3575
RTW_INFO("==> set dm_bt_coexist:%x\n", *(u8 *)pdata);
3576
rtw_hal_set_hwreg(padapter, HW_VAR_BT_SET_COEXIST, pdata);
3577
break;
3578
case GEN_MP_IOCTL_SUBCODE(DEL_BA):
3579
RTW_INFO("==> delete ba:%x\n", *(u8 *)pdata);
3580
rtw_hal_set_hwreg(padapter, HW_VAR_BT_ISSUE_DELBA, pdata);
3581
break;
3582
#endif
3583
#ifdef DBG_CONFIG_ERROR_DETECT
3584
case GEN_MP_IOCTL_SUBCODE(GET_WIFI_STATUS):
3585
*pdata = rtw_hal_sreset_get_wifi_status(padapter);
3586
break;
3587
#endif
3588
3589
default:
3590
break;
3591
}
3592
3593
}
3594
static int rtw_mp_ioctl_hdl(struct net_device *dev, struct iw_request_info *info,
3595
union iwreq_data *wrqu, char *extra)
3596
{
3597
int ret = 0;
3598
u32 BytesRead, BytesWritten, BytesNeeded;
3599
struct oid_par_priv oid_par;
3600
struct mp_ioctl_handler *phandler;
3601
struct mp_ioctl_param *poidparam;
3602
uint status = 0;
3603
u16 len;
3604
u8 *pparmbuf = NULL, bset;
3605
PADAPTER padapter = (PADAPTER)rtw_netdev_priv(dev);
3606
struct iw_point *p = &wrqu->data;
3607
3608
/* RTW_INFO("+rtw_mp_ioctl_hdl\n"); */
3609
3610
/* mutex_lock(&ioctl_mutex); */
3611
3612
if ((!p->length) || (!p->pointer)) {
3613
ret = -EINVAL;
3614
goto _rtw_mp_ioctl_hdl_exit;
3615
}
3616
3617
pparmbuf = NULL;
3618
bset = (u8)(p->flags & 0xFFFF);
3619
len = p->length;
3620
pparmbuf = (u8 *)rtw_malloc(len);
3621
if (pparmbuf == NULL) {
3622
ret = -ENOMEM;
3623
goto _rtw_mp_ioctl_hdl_exit;
3624
}
3625
3626
if (copy_from_user(pparmbuf, p->pointer, len)) {
3627
ret = -EFAULT;
3628
goto _rtw_mp_ioctl_hdl_exit;
3629
}
3630
3631
poidparam = (struct mp_ioctl_param *)pparmbuf;
3632
3633
if (poidparam->subcode >= MAX_MP_IOCTL_SUBCODE) {
3634
ret = -EINVAL;
3635
goto _rtw_mp_ioctl_hdl_exit;
3636
}
3637
3638
/* RTW_INFO("%s: %d\n", __func__, poidparam->subcode); */
3639
#ifdef CONFIG_MP_INCLUDED
3640
if (padapter->registrypriv.mp_mode == 1) {
3641
phandler = mp_ioctl_hdl + poidparam->subcode;
3642
3643
if ((phandler->paramsize != 0) && (poidparam->len < phandler->paramsize)) {
3644
ret = -EINVAL;
3645
goto _rtw_mp_ioctl_hdl_exit;
3646
}
3647
3648
if (phandler->handler) {
3649
oid_par.adapter_context = padapter;
3650
oid_par.oid = phandler->oid;
3651
oid_par.information_buf = poidparam->data;
3652
oid_par.information_buf_len = poidparam->len;
3653
oid_par.dbg = 0;
3654
3655
BytesWritten = 0;
3656
BytesNeeded = 0;
3657
3658
if (bset) {
3659
oid_par.bytes_rw = &BytesRead;
3660
oid_par.bytes_needed = &BytesNeeded;
3661
oid_par.type_of_oid = SET_OID;
3662
} else {
3663
oid_par.bytes_rw = &BytesWritten;
3664
oid_par.bytes_needed = &BytesNeeded;
3665
oid_par.type_of_oid = QUERY_OID;
3666
}
3667
3668
status = phandler->handler(&oid_par);
3669
3670
/* todo:check status, BytesNeeded, etc. */
3671
} else {
3672
RTW_INFO("rtw_mp_ioctl_hdl(): err!, subcode=%d, oid=%d, handler=%p\n",
3673
poidparam->subcode, phandler->oid, phandler->handler);
3674
ret = -EFAULT;
3675
goto _rtw_mp_ioctl_hdl_exit;
3676
}
3677
} else
3678
#endif
3679
{
3680
rtw_dbg_mode_hdl(padapter, poidparam->subcode, poidparam->data, poidparam->len);
3681
}
3682
3683
if (bset == 0x00) {/* query info */
3684
if (copy_to_user(p->pointer, pparmbuf, len))
3685
ret = -EFAULT;
3686
}
3687
3688
if (status) {
3689
ret = -EFAULT;
3690
goto _rtw_mp_ioctl_hdl_exit;
3691
}
3692
3693
_rtw_mp_ioctl_hdl_exit:
3694
3695
if (pparmbuf)
3696
rtw_mfree(pparmbuf, len);
3697
3698
/* mutex_unlock(&ioctl_mutex); */
3699
3700
return ret;
3701
}
3702
#endif /*MP_IOCTL_HDL*/
3703
static int rtw_get_ap_info(struct net_device *dev,
3704
struct iw_request_info *info,
3705
union iwreq_data *wrqu, char *extra)
3706
{
3707
int ret = 0;
3708
u32 cnt = 0, wpa_ielen;
3709
_irqL irqL;
3710
_list *plist, *phead;
3711
unsigned char *pbuf;
3712
u8 bssid[ETH_ALEN];
3713
char data[32];
3714
struct wlan_network *pnetwork = NULL;
3715
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3716
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3717
_queue *queue = &(pmlmepriv->scanned_queue);
3718
struct iw_point *pdata = &wrqu->data;
3719
3720
RTW_INFO("+rtw_get_aplist_info\n");
3721
3722
if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
3723
ret = -EINVAL;
3724
goto exit;
3725
}
3726
3727
while ((check_fwstate(pmlmepriv, (_FW_UNDER_SURVEY | _FW_UNDER_LINKING))) == _TRUE) {
3728
rtw_msleep_os(30);
3729
cnt++;
3730
if (cnt > 100)
3731
break;
3732
}
3733
3734
3735
/* pdata->length = 0; */ /* ? */
3736
pdata->flags = 0;
3737
if (pdata->length >= 32) {
3738
if (copy_from_user(data, pdata->pointer, 32)) {
3739
ret = -EINVAL;
3740
goto exit;
3741
}
3742
} else {
3743
ret = -EINVAL;
3744
goto exit;
3745
}
3746
3747
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3748
3749
phead = get_list_head(queue);
3750
plist = get_next(phead);
3751
3752
while (1) {
3753
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
3754
break;
3755
3756
3757
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
3758
3759
/* if(hwaddr_aton_i(pdata->pointer, bssid)) */
3760
if (hwaddr_aton_i(data, bssid)) {
3761
RTW_INFO("Invalid BSSID '%s'.\n", (u8 *)data);
3762
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3763
return -EINVAL;
3764
}
3765
3766
3767
if (_rtw_memcmp(bssid, pnetwork->network.MacAddress, ETH_ALEN) == _TRUE) { /* BSSID match, then check if supporting wpa/wpa2 */
3768
RTW_INFO("BSSID:" MAC_FMT "\n", MAC_ARG(bssid));
3769
3770
pbuf = rtw_get_wpa_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
3771
if (pbuf && (wpa_ielen > 0)) {
3772
pdata->flags = 1;
3773
break;
3774
}
3775
3776
pbuf = rtw_get_wpa2_ie(&pnetwork->network.IEs[12], &wpa_ielen, pnetwork->network.IELength - 12);
3777
if (pbuf && (wpa_ielen > 0)) {
3778
pdata->flags = 2;
3779
break;
3780
}
3781
3782
}
3783
3784
plist = get_next(plist);
3785
3786
}
3787
3788
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
3789
3790
if (pdata->length >= 34) {
3791
if (copy_to_user((u8 *)pdata->pointer + 32, (u8 *)&pdata->flags, 1)) {
3792
ret = -EINVAL;
3793
goto exit;
3794
}
3795
}
3796
3797
exit:
3798
3799
return ret;
3800
3801
}
3802
3803
static int rtw_set_pid(struct net_device *dev,
3804
struct iw_request_info *info,
3805
union iwreq_data *wrqu, char *extra)
3806
{
3807
3808
int ret = 0;
3809
_adapter *padapter = rtw_netdev_priv(dev);
3810
int *pdata = (int *)wrqu;
3811
int selector;
3812
3813
if (rtw_is_drv_stopped(padapter) || (pdata == NULL)) {
3814
ret = -EINVAL;
3815
goto exit;
3816
}
3817
3818
selector = *pdata;
3819
if (selector < 3 && selector >= 0) {
3820
padapter->pid[selector] = *(pdata + 1);
3821
#ifdef CONFIG_GLOBAL_UI_PID
3822
ui_pid[selector] = *(pdata + 1);
3823
#endif
3824
RTW_INFO("%s set pid[%d]=%d\n", __FUNCTION__, selector , padapter->pid[selector]);
3825
} else
3826
RTW_INFO("%s selector %d error\n", __FUNCTION__, selector);
3827
3828
exit:
3829
3830
return ret;
3831
3832
}
3833
3834
static int rtw_wps_start(struct net_device *dev,
3835
struct iw_request_info *info,
3836
union iwreq_data *wrqu, char *extra)
3837
{
3838
3839
int ret = 0;
3840
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3841
struct iw_point *pdata = &wrqu->data;
3842
u32 u32wps_start = 0;
3843
unsigned int uintRet = 0;
3844
3845
if (RTW_CANNOT_RUN(padapter) || (NULL == pdata)) {
3846
ret = -EINVAL;
3847
goto exit;
3848
}
3849
3850
uintRet = copy_from_user((void *) &u32wps_start, pdata->pointer, 4);
3851
if (u32wps_start == 0)
3852
u32wps_start = *extra;
3853
3854
RTW_INFO("[%s] wps_start = %d\n", __FUNCTION__, u32wps_start);
3855
3856
if (u32wps_start == 1) /* WPS Start */
3857
rtw_led_control(padapter, LED_CTL_START_WPS);
3858
else if (u32wps_start == 2) /* WPS Stop because of wps success */
3859
rtw_led_control(padapter, LED_CTL_STOP_WPS);
3860
else if (u32wps_start == 3) /* WPS Stop because of wps fail */
3861
rtw_led_control(padapter, LED_CTL_STOP_WPS_FAIL);
3862
3863
exit:
3864
3865
return ret;
3866
3867
}
3868
3869
#ifdef CONFIG_P2P
3870
static int rtw_wext_p2p_enable(struct net_device *dev,
3871
struct iw_request_info *info,
3872
union iwreq_data *wrqu, char *extra)
3873
{
3874
3875
int ret = 0;
3876
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3877
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3878
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3879
enum P2P_ROLE init_role = P2P_ROLE_DISABLE;
3880
3881
if (*extra == '0')
3882
init_role = P2P_ROLE_DISABLE;
3883
else if (*extra == '1')
3884
init_role = P2P_ROLE_DEVICE;
3885
else if (*extra == '2')
3886
init_role = P2P_ROLE_CLIENT;
3887
else if (*extra == '3')
3888
init_role = P2P_ROLE_GO;
3889
3890
if (_FAIL == rtw_p2p_enable(padapter, init_role)) {
3891
ret = -EFAULT;
3892
goto exit;
3893
}
3894
3895
/* set channel/bandwidth */
3896
if (init_role != P2P_ROLE_DISABLE) {
3897
u8 channel, ch_offset;
3898
u16 bwmode;
3899
3900
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_LISTEN)) {
3901
/* Stay at the listen state and wait for discovery. */
3902
channel = pwdinfo->listen_channel;
3903
pwdinfo->operating_channel = pwdinfo->listen_channel;
3904
ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
3905
bwmode = CHANNEL_WIDTH_20;
3906
}
3907
#ifdef CONFIG_CONCURRENT_MODE
3908
else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
3909
3910
_set_timer(&pwdinfo->ap_p2p_switch_timer, pwdinfo->ext_listen_interval);
3911
3912
channel = rtw_mi_get_union_chan(padapter);
3913
ch_offset = rtw_mi_get_union_offset(padapter);
3914
bwmode = rtw_mi_get_union_bw(padapter);
3915
3916
pwdinfo->operating_channel = channel;
3917
}
3918
#endif
3919
else {
3920
pwdinfo->operating_channel = pmlmeext->cur_channel;
3921
3922
channel = pwdinfo->operating_channel;
3923
ch_offset = pmlmeext->cur_ch_offset;
3924
bwmode = pmlmeext->cur_bwmode;
3925
}
3926
3927
set_channel_bwmode(padapter, channel, ch_offset, bwmode);
3928
}
3929
3930
exit:
3931
return ret;
3932
3933
}
3934
3935
static int rtw_p2p_set_go_nego_ssid(struct net_device *dev,
3936
struct iw_request_info *info,
3937
union iwreq_data *wrqu, char *extra)
3938
{
3939
3940
int ret = 0;
3941
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3942
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3943
3944
RTW_INFO("[%s] ssid = %s, len = %zu\n", __FUNCTION__, extra, strlen(extra));
3945
_rtw_memcpy(pwdinfo->nego_ssid, extra, strlen(extra));
3946
pwdinfo->nego_ssidlen = strlen(extra);
3947
3948
return ret;
3949
3950
}
3951
3952
3953
static int rtw_p2p_set_intent(struct net_device *dev,
3954
struct iw_request_info *info,
3955
union iwreq_data *wrqu, char *extra)
3956
{
3957
int ret = 0;
3958
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3959
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3960
u8 intent = pwdinfo->intent;
3961
3962
extra[wrqu->data.length] = 0x00;
3963
3964
intent = rtw_atoi(extra);
3965
3966
if (intent <= 15)
3967
pwdinfo->intent = intent;
3968
else
3969
ret = -1;
3970
3971
RTW_INFO("[%s] intent = %d\n", __FUNCTION__, intent);
3972
3973
return ret;
3974
3975
}
3976
3977
static int rtw_p2p_set_listen_ch(struct net_device *dev,
3978
struct iw_request_info *info,
3979
union iwreq_data *wrqu, char *extra)
3980
{
3981
3982
int ret = 0;
3983
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
3984
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3985
u8 listen_ch = pwdinfo->listen_channel; /* Listen channel number */
3986
3987
extra[wrqu->data.length] = 0x00;
3988
listen_ch = rtw_atoi(extra);
3989
3990
if ((listen_ch == 1) || (listen_ch == 6) || (listen_ch == 11)) {
3991
pwdinfo->listen_channel = listen_ch;
3992
set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
3993
} else
3994
ret = -1;
3995
3996
RTW_INFO("[%s] listen_ch = %d\n", __FUNCTION__, pwdinfo->listen_channel);
3997
3998
return ret;
3999
4000
}
4001
4002
static int rtw_p2p_set_op_ch(struct net_device *dev,
4003
struct iw_request_info *info,
4004
union iwreq_data *wrqu, char *extra)
4005
{
4006
/* Commented by Albert 20110524
4007
* This function is used to set the operating channel if the driver will become the group owner */
4008
4009
int ret = 0;
4010
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4011
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4012
u8 op_ch = pwdinfo->operating_channel; /* Operating channel number */
4013
4014
extra[wrqu->data.length] = 0x00;
4015
4016
op_ch = (u8) rtw_atoi(extra);
4017
if (op_ch > 0)
4018
pwdinfo->operating_channel = op_ch;
4019
else
4020
ret = -1;
4021
4022
RTW_INFO("[%s] op_ch = %d\n", __FUNCTION__, pwdinfo->operating_channel);
4023
4024
return ret;
4025
4026
}
4027
4028
4029
static int rtw_p2p_profilefound(struct net_device *dev,
4030
struct iw_request_info *info,
4031
union iwreq_data *wrqu, char *extra)
4032
{
4033
4034
int ret = 0;
4035
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4036
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4037
4038
/* Comment by Albert 2010/10/13 */
4039
/* Input data format: */
4040
/* Ex: 0 */
4041
/* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
4042
/* 0 => Reflush the profile record list. */
4043
/* 1 => Add the profile list */
4044
/* XX:XX:XX:XX:XX:XX => peer's MAC Address ( ex: 00:E0:4C:00:00:01 ) */
4045
/* YY => SSID Length */
4046
/* SSID => SSID for persistence group */
4047
4048
RTW_INFO("[%s] In value = %s, len = %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4049
4050
4051
/* The upper application should pass the SSID to driver by using this rtw_p2p_profilefound function. */
4052
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4053
if (extra[0] == '0') {
4054
/* Remove all the profile information of wifidirect_info structure. */
4055
_rtw_memset(&pwdinfo->profileinfo[0], 0x00, sizeof(struct profile_info) * P2P_MAX_PERSISTENT_GROUP_NUM);
4056
pwdinfo->profileindex = 0;
4057
} else {
4058
if (pwdinfo->profileindex >= P2P_MAX_PERSISTENT_GROUP_NUM)
4059
ret = -1;
4060
else {
4061
int jj, kk;
4062
4063
/* Add this profile information into pwdinfo->profileinfo */
4064
/* Ex: 1XX:XX:XX:XX:XX:XXYYSSID */
4065
for (jj = 0, kk = 1; jj < ETH_ALEN; jj++, kk += 3)
4066
pwdinfo->profileinfo[pwdinfo->profileindex].peermac[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4067
4068
/* pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen = ( extra[18] - '0' ) * 10 + ( extra[19] - '0' ); */
4069
/* _rtw_memcpy( pwdinfo->profileinfo[pwdinfo->profileindex].ssid, &extra[20], pwdinfo->profileinfo[pwdinfo->profileindex].ssidlen ); */
4070
pwdinfo->profileindex++;
4071
}
4072
}
4073
}
4074
4075
return ret;
4076
4077
}
4078
4079
static int rtw_p2p_setDN(struct net_device *dev,
4080
struct iw_request_info *info,
4081
union iwreq_data *wrqu, char *extra)
4082
{
4083
4084
int ret = 0;
4085
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4086
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4087
4088
4089
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
4090
_rtw_memset(pwdinfo->device_name, 0x00, WPS_MAX_DEVICE_NAME_LEN);
4091
_rtw_memcpy(pwdinfo->device_name, extra, wrqu->data.length - 1);
4092
pwdinfo->device_name_len = wrqu->data.length - 1;
4093
4094
return ret;
4095
4096
}
4097
4098
4099
static int rtw_p2p_get_status(struct net_device *dev,
4100
struct iw_request_info *info,
4101
union iwreq_data *wrqu, char *extra)
4102
{
4103
4104
int ret = 0;
4105
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4106
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4107
4108
if (padapter->bShowGetP2PState) {
4109
RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4110
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4111
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4112
}
4113
4114
/* Commented by Albert 2010/10/12 */
4115
/* Because of the output size limitation, I had removed the "Role" information. */
4116
/* About the "Role" information, we will use the new private IOCTL to get the "Role" information. */
4117
sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
4118
wrqu->data.length = strlen(extra);
4119
4120
return ret;
4121
4122
}
4123
4124
/* Commented by Albert 20110520
4125
* This function will return the config method description
4126
* This config method description will show us which config method the remote P2P device is intented to use
4127
* by sending the provisioning discovery request frame. */
4128
4129
static int rtw_p2p_get_req_cm(struct net_device *dev,
4130
struct iw_request_info *info,
4131
union iwreq_data *wrqu, char *extra)
4132
{
4133
4134
int ret = 0;
4135
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4136
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4137
4138
sprintf(extra, "\n\nCM=%s\n", pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req);
4139
wrqu->data.length = strlen(extra);
4140
return ret;
4141
4142
}
4143
4144
4145
static int rtw_p2p_get_role(struct net_device *dev,
4146
struct iw_request_info *info,
4147
union iwreq_data *wrqu, char *extra)
4148
{
4149
4150
int ret = 0;
4151
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4152
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4153
4154
RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4155
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4156
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4157
4158
sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
4159
wrqu->data.length = strlen(extra);
4160
return ret;
4161
4162
}
4163
4164
4165
static int rtw_p2p_get_peer_ifaddr(struct net_device *dev,
4166
struct iw_request_info *info,
4167
union iwreq_data *wrqu, char *extra)
4168
{
4169
4170
int ret = 0;
4171
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4172
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4173
4174
4175
RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4176
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4177
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4178
4179
sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4180
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1], pwdinfo->p2p_peer_interface_addr[2],
4181
pwdinfo->p2p_peer_interface_addr[3], pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
4182
wrqu->data.length = strlen(extra);
4183
return ret;
4184
4185
}
4186
4187
static int rtw_p2p_get_peer_devaddr(struct net_device *dev,
4188
struct iw_request_info *info,
4189
union iwreq_data *wrqu, char *extra)
4190
4191
{
4192
4193
int ret = 0;
4194
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4195
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4196
4197
RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4198
pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4199
pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4200
pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4201
sprintf(extra, "\n%.2X%.2X%.2X%.2X%.2X%.2X",
4202
pwdinfo->rx_prov_disc_info.peerDevAddr[0], pwdinfo->rx_prov_disc_info.peerDevAddr[1],
4203
pwdinfo->rx_prov_disc_info.peerDevAddr[2], pwdinfo->rx_prov_disc_info.peerDevAddr[3],
4204
pwdinfo->rx_prov_disc_info.peerDevAddr[4], pwdinfo->rx_prov_disc_info.peerDevAddr[5]);
4205
wrqu->data.length = strlen(extra);
4206
return ret;
4207
4208
}
4209
4210
static int rtw_p2p_get_peer_devaddr_by_invitation(struct net_device *dev,
4211
struct iw_request_info *info,
4212
union iwreq_data *wrqu, char *extra)
4213
4214
{
4215
4216
int ret = 0;
4217
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4218
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4219
4220
RTW_INFO("[%s] Role = %d, Status = %d, peer addr = %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", __FUNCTION__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo),
4221
pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4222
pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4223
pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4224
sprintf(extra, "\nMAC %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4225
pwdinfo->p2p_peer_device_addr[0], pwdinfo->p2p_peer_device_addr[1],
4226
pwdinfo->p2p_peer_device_addr[2], pwdinfo->p2p_peer_device_addr[3],
4227
pwdinfo->p2p_peer_device_addr[4], pwdinfo->p2p_peer_device_addr[5]);
4228
wrqu->data.length = strlen(extra);
4229
return ret;
4230
4231
}
4232
4233
static int rtw_p2p_get_groupid(struct net_device *dev,
4234
struct iw_request_info *info,
4235
union iwreq_data *wrqu, char *extra)
4236
4237
{
4238
4239
int ret = 0;
4240
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4241
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4242
4243
sprintf(extra, "\n%.2X:%.2X:%.2X:%.2X:%.2X:%.2X %s",
4244
pwdinfo->groupid_info.go_device_addr[0], pwdinfo->groupid_info.go_device_addr[1],
4245
pwdinfo->groupid_info.go_device_addr[2], pwdinfo->groupid_info.go_device_addr[3],
4246
pwdinfo->groupid_info.go_device_addr[4], pwdinfo->groupid_info.go_device_addr[5],
4247
pwdinfo->groupid_info.ssid);
4248
wrqu->data.length = strlen(extra);
4249
return ret;
4250
4251
}
4252
4253
static int rtw_p2p_get_op_ch(struct net_device *dev,
4254
struct iw_request_info *info,
4255
union iwreq_data *wrqu, char *extra)
4256
4257
{
4258
4259
int ret = 0;
4260
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4261
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4262
4263
4264
RTW_INFO("[%s] Op_ch = %02x\n", __FUNCTION__, pwdinfo->operating_channel);
4265
4266
sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
4267
wrqu->data.length = strlen(extra);
4268
return ret;
4269
4270
}
4271
4272
static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
4273
struct iw_request_info *info,
4274
union iwreq_data *wrqu, char *extra, char *subcmd)
4275
{
4276
4277
int ret = 0;
4278
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4279
u8 peerMAC[ETH_ALEN] = { 0x00 };
4280
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4281
_irqL irqL;
4282
_list *plist, *phead;
4283
_queue *queue = &(pmlmepriv->scanned_queue);
4284
struct wlan_network *pnetwork = NULL;
4285
u8 blnMatch = 0;
4286
u16 attr_content = 0;
4287
uint attr_contentlen = 0;
4288
u8 attr_content_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4289
4290
/* Commented by Albert 20110727 */
4291
/* The input data is the MAC address which the application wants to know its WPS config method. */
4292
/* After knowing its WPS config method, the application can decide the config method for provisioning discovery. */
4293
/* Format: iwpriv wlanx p2p_get_wpsCM 00:E0:4C:00:00:05 */
4294
4295
RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4296
4297
macstr2num(peerMAC, subcmd);
4298
4299
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4300
4301
phead = get_list_head(queue);
4302
plist = get_next(phead);
4303
4304
while (1) {
4305
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4306
break;
4307
4308
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4309
if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4310
u8 *wpsie;
4311
uint wpsie_len = 0;
4312
4313
/* The mac address is matched. */
4314
4315
wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4316
if (wpsie) {
4317
rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_CONF_METHOD, (u8 *)&attr_content, &attr_contentlen);
4318
if (attr_contentlen) {
4319
attr_content = be16_to_cpu(attr_content);
4320
sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
4321
blnMatch = 1;
4322
}
4323
}
4324
4325
break;
4326
}
4327
4328
plist = get_next(plist);
4329
4330
}
4331
4332
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4333
4334
if (!blnMatch)
4335
sprintf(attr_content_str, "\n\nM=0000");
4336
4337
wrqu->data.length = strlen(attr_content_str);
4338
_rtw_memcpy(extra, attr_content_str, wrqu->data.length);
4339
4340
return ret;
4341
4342
}
4343
4344
#ifdef CONFIG_WFD
4345
static int rtw_p2p_get_peer_wfd_port(struct net_device *dev,
4346
struct iw_request_info *info,
4347
union iwreq_data *wrqu, char *extra)
4348
{
4349
4350
int ret = 0;
4351
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4352
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4353
4354
RTW_INFO("[%s] p2p_state = %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
4355
4356
sprintf(extra, "\n\nPort=%d\n", pwdinfo->wfd_info->peer_rtsp_ctrlport);
4357
RTW_INFO("[%s] remote port = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_rtsp_ctrlport);
4358
4359
wrqu->data.length = strlen(extra);
4360
return ret;
4361
4362
}
4363
4364
static int rtw_p2p_get_peer_wfd_preferred_connection(struct net_device *dev,
4365
struct iw_request_info *info,
4366
union iwreq_data *wrqu, char *extra)
4367
{
4368
4369
int ret = 0;
4370
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4371
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4372
4373
sprintf(extra, "\n\nwfd_pc=%d\n", pwdinfo->wfd_info->wfd_pc);
4374
RTW_INFO("[%s] wfd_pc = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_pc);
4375
4376
wrqu->data.length = strlen(extra);
4377
pwdinfo->wfd_info->wfd_pc = _FALSE; /* Reset the WFD preferred connection to P2P */
4378
return ret;
4379
4380
}
4381
4382
static int rtw_p2p_get_peer_wfd_session_available(struct net_device *dev,
4383
struct iw_request_info *info,
4384
union iwreq_data *wrqu, char *extra)
4385
{
4386
4387
int ret = 0;
4388
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4389
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4390
4391
sprintf(extra, "\n\nwfd_sa=%d\n", pwdinfo->wfd_info->peer_session_avail);
4392
RTW_INFO("[%s] wfd_sa = %d\n", __FUNCTION__, pwdinfo->wfd_info->peer_session_avail);
4393
4394
wrqu->data.length = strlen(extra);
4395
pwdinfo->wfd_info->peer_session_avail = _TRUE; /* Reset the WFD session available */
4396
return ret;
4397
4398
}
4399
#endif /* CONFIG_WFD */
4400
4401
static int rtw_p2p_get_go_device_address(struct net_device *dev,
4402
struct iw_request_info *info,
4403
union iwreq_data *wrqu, char *extra, char *subcmd)
4404
{
4405
4406
int ret = 0;
4407
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4408
u8 peerMAC[ETH_ALEN] = { 0x00 };
4409
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4410
_irqL irqL;
4411
_list *plist, *phead;
4412
_queue *queue = &(pmlmepriv->scanned_queue);
4413
struct wlan_network *pnetwork = NULL;
4414
u8 blnMatch = 0;
4415
u8 *p2pie;
4416
uint p2pielen = 0, attr_contentlen = 0;
4417
u8 attr_content[100] = { 0x00 };
4418
u8 go_devadd_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4419
4420
/* Commented by Albert 20121209 */
4421
/* The input data is the GO's interface address which the application wants to know its device address. */
4422
/* Format: iwpriv wlanx p2p_get2 go_devadd=00:E0:4C:00:00:05 */
4423
4424
RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4425
4426
macstr2num(peerMAC, subcmd);
4427
4428
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4429
4430
phead = get_list_head(queue);
4431
plist = get_next(phead);
4432
4433
while (1) {
4434
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4435
break;
4436
4437
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4438
if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4439
/* Commented by Albert 2011/05/18 */
4440
/* Match the device address located in the P2P IE */
4441
/* This is for the case that the P2P device address is not the same as the P2P interface address. */
4442
4443
p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4444
if (p2pie) {
4445
while (p2pie) {
4446
/* The P2P Device ID attribute is included in the Beacon frame. */
4447
/* The P2P Device Info attribute is included in the probe response frame. */
4448
4449
_rtw_memset(attr_content, 0x00, 100);
4450
if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
4451
/* Handle the P2P Device ID attribute of Beacon first */
4452
blnMatch = 1;
4453
break;
4454
4455
} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
4456
/* Handle the P2P Device Info attribute of probe response */
4457
blnMatch = 1;
4458
break;
4459
}
4460
4461
/* Get the next P2P IE */
4462
p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
4463
}
4464
}
4465
}
4466
4467
plist = get_next(plist);
4468
4469
}
4470
4471
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4472
4473
if (!blnMatch)
4474
sprintf(go_devadd_str, "\n\ndev_add=NULL");
4475
else {
4476
sprintf(go_devadd_str, "\n\ndev_add=%.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
4477
attr_content[0], attr_content[1], attr_content[2], attr_content[3], attr_content[4], attr_content[5]);
4478
}
4479
4480
wrqu->data.length = strlen(go_devadd_str);
4481
_rtw_memcpy(extra, go_devadd_str, wrqu->data.length);
4482
4483
return ret;
4484
4485
}
4486
4487
static int rtw_p2p_get_device_type(struct net_device *dev,
4488
struct iw_request_info *info,
4489
union iwreq_data *wrqu, char *extra, char *subcmd)
4490
{
4491
4492
int ret = 0;
4493
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4494
u8 peerMAC[ETH_ALEN] = { 0x00 };
4495
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4496
_irqL irqL;
4497
_list *plist, *phead;
4498
_queue *queue = &(pmlmepriv->scanned_queue);
4499
struct wlan_network *pnetwork = NULL;
4500
u8 blnMatch = 0;
4501
u8 dev_type[8] = { 0x00 };
4502
uint dev_type_len = 0;
4503
u8 dev_type_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 }; /* +9 is for the str "dev_type=", we have to clear it at wrqu->data.pointer */
4504
4505
/* Commented by Albert 20121209 */
4506
/* The input data is the MAC address which the application wants to know its device type. */
4507
/* Such user interface could know the device type. */
4508
/* Format: iwpriv wlanx p2p_get2 dev_type=00:E0:4C:00:00:05 */
4509
4510
RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4511
4512
macstr2num(peerMAC, subcmd);
4513
4514
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4515
4516
phead = get_list_head(queue);
4517
plist = get_next(phead);
4518
4519
while (1) {
4520
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4521
break;
4522
4523
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4524
if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4525
u8 *wpsie;
4526
uint wpsie_len = 0;
4527
4528
/* The mac address is matched. */
4529
4530
wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4531
if (wpsie) {
4532
rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_PRIMARY_DEV_TYPE, dev_type, &dev_type_len);
4533
if (dev_type_len) {
4534
u16 type = 0;
4535
4536
_rtw_memcpy(&type, dev_type, 2);
4537
type = be16_to_cpu(type);
4538
sprintf(dev_type_str, "\n\nN=%.2d", type);
4539
blnMatch = 1;
4540
}
4541
}
4542
break;
4543
}
4544
4545
plist = get_next(plist);
4546
4547
}
4548
4549
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4550
4551
if (!blnMatch)
4552
sprintf(dev_type_str, "\n\nN=00");
4553
4554
wrqu->data.length = strlen(dev_type_str);
4555
_rtw_memcpy(extra, dev_type_str, wrqu->data.length);
4556
4557
return ret;
4558
4559
}
4560
4561
static int rtw_p2p_get_device_name(struct net_device *dev,
4562
struct iw_request_info *info,
4563
union iwreq_data *wrqu, char *extra, char *subcmd)
4564
{
4565
4566
int ret = 0;
4567
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4568
u8 peerMAC[ETH_ALEN] = { 0x00 };
4569
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4570
_irqL irqL;
4571
_list *plist, *phead;
4572
_queue *queue = &(pmlmepriv->scanned_queue);
4573
struct wlan_network *pnetwork = NULL;
4574
u8 blnMatch = 0;
4575
u8 dev_name[WPS_MAX_DEVICE_NAME_LEN] = { 0x00 };
4576
uint dev_len = 0;
4577
u8 dev_name_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4578
4579
/* Commented by Albert 20121225 */
4580
/* The input data is the MAC address which the application wants to know its device name. */
4581
/* Such user interface could show peer device's device name instead of ssid. */
4582
/* Format: iwpriv wlanx p2p_get2 devN=00:E0:4C:00:00:05 */
4583
4584
RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4585
4586
macstr2num(peerMAC, subcmd);
4587
4588
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4589
4590
phead = get_list_head(queue);
4591
plist = get_next(phead);
4592
4593
while (1) {
4594
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4595
break;
4596
4597
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4598
if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4599
u8 *wpsie;
4600
uint wpsie_len = 0;
4601
4602
/* The mac address is matched. */
4603
4604
wpsie = rtw_get_wps_ie_from_scan_queue(&pnetwork->network.IEs[0], pnetwork->network.IELength, NULL, &wpsie_len, pnetwork->network.Reserved[0]);
4605
if (wpsie) {
4606
rtw_get_wps_attr_content(wpsie, wpsie_len, WPS_ATTR_DEVICE_NAME, dev_name, &dev_len);
4607
if (dev_len) {
4608
sprintf(dev_name_str, "\n\nN=%s", dev_name);
4609
blnMatch = 1;
4610
}
4611
}
4612
break;
4613
}
4614
4615
plist = get_next(plist);
4616
4617
}
4618
4619
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4620
4621
if (!blnMatch)
4622
sprintf(dev_name_str, "\n\nN=0000");
4623
4624
wrqu->data.length = strlen(dev_name_str);
4625
_rtw_memcpy(extra, dev_name_str, wrqu->data.length);
4626
4627
return ret;
4628
4629
}
4630
4631
static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
4632
struct iw_request_info *info,
4633
union iwreq_data *wrqu, char *extra, char *subcmd)
4634
{
4635
4636
int ret = 0;
4637
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4638
u8 peerMAC[ETH_ALEN] = { 0x00 };
4639
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4640
_irqL irqL;
4641
_list *plist, *phead;
4642
_queue *queue = &(pmlmepriv->scanned_queue);
4643
struct wlan_network *pnetwork = NULL;
4644
u8 blnMatch = 0;
4645
u8 *p2pie;
4646
uint p2pielen = 0, attr_contentlen = 0;
4647
u8 attr_content[2] = { 0x00 };
4648
u8 inv_proc_str[P2P_PRIVATE_IOCTL_SET_LEN] = { 0x00 };
4649
4650
/* Commented by Ouden 20121226 */
4651
/* The application wants to know P2P initation procedure is support or not. */
4652
/* Format: iwpriv wlanx p2p_get2 InvProc=00:E0:4C:00:00:05 */
4653
4654
RTW_INFO("[%s] data = %s\n", __FUNCTION__, subcmd);
4655
4656
macstr2num(peerMAC, subcmd);
4657
4658
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4659
4660
phead = get_list_head(queue);
4661
plist = get_next(phead);
4662
4663
while (1) {
4664
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4665
break;
4666
4667
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4668
if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4669
/* Commented by Albert 20121226 */
4670
/* Match the device address located in the P2P IE */
4671
/* This is for the case that the P2P device address is not the same as the P2P interface address. */
4672
4673
p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4674
if (p2pie) {
4675
while (p2pie) {
4676
/* _rtw_memset( attr_content, 0x00, 2); */
4677
if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_CAPABILITY, attr_content, &attr_contentlen)) {
4678
/* Handle the P2P capability attribute */
4679
blnMatch = 1;
4680
break;
4681
4682
}
4683
4684
/* Get the next P2P IE */
4685
p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
4686
}
4687
}
4688
}
4689
4690
plist = get_next(plist);
4691
4692
}
4693
4694
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4695
4696
if (!blnMatch)
4697
sprintf(inv_proc_str, "\nIP=-1");
4698
else {
4699
if ((attr_content[0] & 0x20) == 0x20)
4700
sprintf(inv_proc_str, "\nIP=1");
4701
else
4702
sprintf(inv_proc_str, "\nIP=0");
4703
}
4704
4705
wrqu->data.length = strlen(inv_proc_str);
4706
_rtw_memcpy(extra, inv_proc_str, wrqu->data.length);
4707
4708
return ret;
4709
4710
}
4711
4712
static int rtw_p2p_connect(struct net_device *dev,
4713
struct iw_request_info *info,
4714
union iwreq_data *wrqu, char *extra)
4715
{
4716
4717
int ret = 0;
4718
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4719
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4720
u8 peerMAC[ETH_ALEN] = { 0x00 };
4721
int jj, kk;
4722
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4723
_irqL irqL;
4724
_list *plist, *phead;
4725
_queue *queue = &(pmlmepriv->scanned_queue);
4726
struct wlan_network *pnetwork = NULL;
4727
uint uintPeerChannel = 0;
4728
4729
/* Commented by Albert 20110304 */
4730
/* The input data contains two informations. */
4731
/* 1. First information is the MAC address which wants to formate with */
4732
/* 2. Second information is the WPS PINCode or "pbc" string for push button method */
4733
/* Format: 00:E0:4C:00:00:05 */
4734
/* Format: 00:E0:4C:00:00:05 */
4735
4736
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
4737
4738
if (pwdinfo->p2p_state == P2P_STATE_NONE) {
4739
RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
4740
return ret;
4741
}
4742
4743
if (pwdinfo->ui_got_wps_info == P2P_NO_WPSINFO)
4744
return -1;
4745
4746
for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4747
peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4748
4749
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4750
4751
phead = get_list_head(queue);
4752
plist = get_next(phead);
4753
4754
while (1) {
4755
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4756
break;
4757
4758
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4759
if (_rtw_memcmp(pnetwork->network.MacAddress, peerMAC, ETH_ALEN)) {
4760
if (pnetwork->network.Configuration.DSConfig != 0)
4761
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4762
else if (pwdinfo->nego_req_info.peer_ch != 0)
4763
uintPeerChannel = pnetwork->network.Configuration.DSConfig = pwdinfo->nego_req_info.peer_ch;
4764
else {
4765
/* Unexpected case */
4766
uintPeerChannel = 0;
4767
RTW_INFO("%s uintPeerChannel = 0\n", __func__);
4768
}
4769
break;
4770
}
4771
4772
plist = get_next(plist);
4773
4774
}
4775
4776
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4777
4778
if (uintPeerChannel) {
4779
#ifdef CONFIG_CONCURRENT_MODE
4780
if (rtw_mi_check_status(padapter, MI_LINKED))
4781
_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
4782
#endif /* CONFIG_CONCURRENT_MODE */
4783
4784
_rtw_memset(&pwdinfo->nego_req_info, 0x00, sizeof(struct tx_nego_req_info));
4785
_rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
4786
4787
pwdinfo->nego_req_info.peer_channel_num[0] = uintPeerChannel;
4788
_rtw_memcpy(pwdinfo->nego_req_info.peerDevAddr, pnetwork->network.MacAddress, ETH_ALEN);
4789
pwdinfo->nego_req_info.benable = _TRUE;
4790
4791
_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
4792
if (rtw_p2p_state(pwdinfo) != P2P_STATE_GONEGO_OK) {
4793
/* Restore to the listen state if the current p2p state is not nego OK */
4794
rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
4795
}
4796
4797
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4798
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_ING);
4799
4800
#ifdef CONFIG_CONCURRENT_MODE
4801
if (rtw_mi_check_status(padapter, MI_LINKED)) {
4802
u8 union_ch = rtw_mi_get_union_chan(padapter);
4803
u8 union_bw = rtw_mi_get_union_bw(padapter);
4804
u8 union_offset = rtw_mi_get_union_offset(padapter);
4805
4806
set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
4807
rtw_leave_opch(padapter);
4808
}
4809
#endif /* CONFIG_CONCURRENT_MODE */
4810
4811
RTW_INFO("[%s] Start PreTx Procedure!\n", __FUNCTION__);
4812
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
4813
#ifdef CONFIG_CONCURRENT_MODE
4814
if (rtw_mi_check_status(padapter, MI_LINKED))
4815
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_GO_NEGO_TIMEOUT);
4816
else
4817
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
4818
#else
4819
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_GO_NEGO_TIMEOUT);
4820
#endif /* CONFIG_CONCURRENT_MODE */
4821
4822
} else {
4823
RTW_INFO("[%s] Not Found in Scanning Queue~\n", __FUNCTION__);
4824
ret = -1;
4825
}
4826
4827
return ret;
4828
}
4829
4830
static int rtw_p2p_invite_req(struct net_device *dev,
4831
struct iw_request_info *info,
4832
union iwreq_data *wrqu, char *extra)
4833
{
4834
4835
int ret = 0;
4836
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
4837
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4838
int jj, kk;
4839
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4840
_list *plist, *phead;
4841
_queue *queue = &(pmlmepriv->scanned_queue);
4842
struct wlan_network *pnetwork = NULL;
4843
uint uintPeerChannel = 0;
4844
u8 attr_content[50] = { 0x00 };
4845
u8 *p2pie;
4846
uint p2pielen = 0, attr_contentlen = 0;
4847
_irqL irqL;
4848
struct tx_invite_req_info *pinvite_req_info = &pwdinfo->invitereq_info;
4849
4850
/* Commented by Albert 20120321 */
4851
/* The input data contains two informations. */
4852
/* 1. First information is the P2P device address which you want to send to. */
4853
/* 2. Second information is the group id which combines with GO's mac address, space and GO's ssid. */
4854
/* Command line sample: iwpriv wlan0 p2p_set invite="00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy" */
4855
/* Format: 00:11:22:33:44:55 00:E0:4C:00:00:05 DIRECT-xy */
4856
4857
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
4858
4859
if (wrqu->data.length <= 37) {
4860
RTW_INFO("[%s] Wrong format!\n", __FUNCTION__);
4861
return ret;
4862
}
4863
4864
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4865
RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
4866
return ret;
4867
} else {
4868
/* Reset the content of struct tx_invite_req_info */
4869
pinvite_req_info->benable = _FALSE;
4870
_rtw_memset(pinvite_req_info->go_bssid, 0x00, ETH_ALEN);
4871
_rtw_memset(pinvite_req_info->go_ssid, 0x00, WLAN_SSID_MAXLEN);
4872
pinvite_req_info->ssidlen = 0x00;
4873
pinvite_req_info->operating_ch = pwdinfo->operating_channel;
4874
_rtw_memset(pinvite_req_info->peer_macaddr, 0x00, ETH_ALEN);
4875
pinvite_req_info->token = 3;
4876
}
4877
4878
for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
4879
pinvite_req_info->peer_macaddr[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4880
4881
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4882
4883
phead = get_list_head(queue);
4884
plist = get_next(phead);
4885
4886
while (1) {
4887
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
4888
break;
4889
4890
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
4891
4892
/* Commented by Albert 2011/05/18 */
4893
/* Match the device address located in the P2P IE */
4894
/* This is for the case that the P2P device address is not the same as the P2P interface address. */
4895
4896
p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
4897
if (p2pie) {
4898
/* The P2P Device ID attribute is included in the Beacon frame. */
4899
/* The P2P Device Info attribute is included in the probe response frame. */
4900
4901
if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
4902
/* Handle the P2P Device ID attribute of Beacon first */
4903
if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
4904
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4905
break;
4906
}
4907
} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
4908
/* Handle the P2P Device Info attribute of probe response */
4909
if (_rtw_memcmp(attr_content, pinvite_req_info->peer_macaddr, ETH_ALEN)) {
4910
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
4911
break;
4912
}
4913
}
4914
4915
}
4916
4917
plist = get_next(plist);
4918
4919
}
4920
4921
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
4922
4923
#ifdef CONFIG_WFD
4924
if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST) && uintPeerChannel) {
4925
struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
4926
u8 *wfd_ie;
4927
uint wfd_ielen = 0;
4928
4929
wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
4930
if (wfd_ie) {
4931
u8 *wfd_devinfo;
4932
uint wfd_devlen;
4933
4934
RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
4935
wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
4936
if (wfd_devinfo) {
4937
u16 wfd_devinfo_field = 0;
4938
4939
/* Commented by Albert 20120319 */
4940
/* The first two bytes are the WFD device information field of WFD device information subelement. */
4941
/* In big endian format. */
4942
wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
4943
if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
4944
pwfd_info->peer_session_avail = _TRUE;
4945
else
4946
pwfd_info->peer_session_avail = _FALSE;
4947
}
4948
}
4949
4950
if (_FALSE == pwfd_info->peer_session_avail) {
4951
RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
4952
goto exit;
4953
}
4954
}
4955
#endif /* CONFIG_WFD */
4956
4957
if (uintPeerChannel) {
4958
#ifdef CONFIG_CONCURRENT_MODE
4959
if (rtw_mi_check_status(padapter, MI_LINKED))
4960
_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
4961
#endif /* CONFIG_CONCURRENT_MODE */
4962
4963
/* Store the GO's bssid */
4964
for (jj = 0, kk = 18; jj < ETH_ALEN; jj++, kk += 3)
4965
pinvite_req_info->go_bssid[jj] = key_2char2num(extra[kk], extra[kk + 1]);
4966
4967
/* Store the GO's ssid */
4968
pinvite_req_info->ssidlen = wrqu->data.length - 36;
4969
_rtw_memcpy(pinvite_req_info->go_ssid, &extra[36], (u32) pinvite_req_info->ssidlen);
4970
pinvite_req_info->benable = _TRUE;
4971
pinvite_req_info->peer_ch = uintPeerChannel;
4972
4973
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
4974
rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_INVITE_REQ);
4975
4976
#ifdef CONFIG_CONCURRENT_MODE
4977
if (rtw_mi_check_status(padapter, MI_LINKED)) {
4978
u8 union_ch = rtw_mi_get_union_chan(padapter);
4979
u8 union_bw = rtw_mi_get_union_bw(padapter);
4980
u8 union_offset = rtw_mi_get_union_offset(padapter);
4981
4982
set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
4983
rtw_leave_opch(padapter);
4984
4985
} else
4986
set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4987
#else
4988
set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
4989
#endif/*CONFIG_CONCURRENT_MODE*/
4990
4991
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
4992
4993
#ifdef CONFIG_CONCURRENT_MODE
4994
if (rtw_mi_check_status(padapter, MI_LINKED))
4995
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_INVITE_TIMEOUT);
4996
else
4997
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
4998
#else
4999
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_INVITE_TIMEOUT);
5000
#endif /* CONFIG_CONCURRENT_MODE */
5001
5002
5003
} else
5004
RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5005
exit:
5006
5007
return ret;
5008
5009
}
5010
5011
static int rtw_p2p_set_persistent(struct net_device *dev,
5012
struct iw_request_info *info,
5013
union iwreq_data *wrqu, char *extra)
5014
{
5015
5016
int ret = 0;
5017
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5018
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5019
5020
/* Commented by Albert 20120328 */
5021
/* The input data is 0 or 1 */
5022
/* 0: disable persistent group functionality */
5023
/* 1: enable persistent group founctionality */
5024
5025
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5026
5027
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5028
RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5029
return ret;
5030
} else {
5031
if (extra[0] == '0') /* Disable the persistent group function. */
5032
pwdinfo->persistent_supported = _FALSE;
5033
else if (extra[0] == '1') /* Enable the persistent group function. */
5034
pwdinfo->persistent_supported = _TRUE;
5035
else
5036
pwdinfo->persistent_supported = _FALSE;
5037
}
5038
printk("[%s] persistent_supported = %d\n", __FUNCTION__, pwdinfo->persistent_supported);
5039
5040
return ret;
5041
5042
}
5043
5044
static int uuid_str2bin(const char *str, u8 *bin)
5045
{
5046
const char *pos;
5047
u8 *opos;
5048
5049
pos = str;
5050
opos = bin;
5051
5052
if (hexstr2bin(pos, opos, 4))
5053
return -1;
5054
pos += 8;
5055
opos += 4;
5056
5057
if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5058
return -1;
5059
pos += 4;
5060
opos += 2;
5061
5062
if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5063
return -1;
5064
pos += 4;
5065
opos += 2;
5066
5067
if (*pos++ != '-' || hexstr2bin(pos, opos, 2))
5068
return -1;
5069
pos += 4;
5070
opos += 2;
5071
5072
if (*pos++ != '-' || hexstr2bin(pos, opos, 6))
5073
return -1;
5074
5075
return 0;
5076
}
5077
5078
static int rtw_p2p_set_wps_uuid(struct net_device *dev,
5079
struct iw_request_info *info,
5080
union iwreq_data *wrqu, char *extra)
5081
{
5082
5083
int ret = 0;
5084
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5085
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5086
5087
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5088
5089
if ((36 == strlen(extra)) && (uuid_str2bin(extra, pwdinfo->uuid) == 0))
5090
pwdinfo->external_uuid = 1;
5091
else {
5092
pwdinfo->external_uuid = 0;
5093
ret = -EINVAL;
5094
}
5095
5096
return ret;
5097
5098
}
5099
#ifdef CONFIG_WFD
5100
static int rtw_p2p_set_pc(struct net_device *dev,
5101
struct iw_request_info *info,
5102
union iwreq_data *wrqu, char *extra)
5103
{
5104
5105
int ret = 0;
5106
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5107
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5108
u8 peerMAC[ETH_ALEN] = { 0x00 };
5109
int jj, kk;
5110
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5111
_list *plist, *phead;
5112
_queue *queue = &(pmlmepriv->scanned_queue);
5113
struct wlan_network *pnetwork = NULL;
5114
u8 attr_content[50] = { 0x00 };
5115
u8 *p2pie;
5116
uint p2pielen = 0, attr_contentlen = 0;
5117
_irqL irqL;
5118
uint uintPeerChannel = 0;
5119
5120
struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5121
5122
/* Commented by Albert 20120512 */
5123
/* 1. Input information is the MAC address which wants to know the Preferred Connection bit (PC bit) */
5124
/* Format: 00:E0:4C:00:00:05 */
5125
5126
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5127
5128
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
5129
RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5130
return ret;
5131
}
5132
5133
for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5134
peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5135
5136
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5137
5138
phead = get_list_head(queue);
5139
plist = get_next(phead);
5140
5141
while (1) {
5142
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5143
break;
5144
5145
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5146
5147
/* Commented by Albert 2011/05/18 */
5148
/* Match the device address located in the P2P IE */
5149
/* This is for the case that the P2P device address is not the same as the P2P interface address. */
5150
5151
p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5152
if (p2pie) {
5153
/* The P2P Device ID attribute is included in the Beacon frame. */
5154
/* The P2P Device Info attribute is included in the probe response frame. */
5155
printk("[%s] Got P2P IE\n", __FUNCTION__);
5156
if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5157
/* Handle the P2P Device ID attribute of Beacon first */
5158
printk("[%s] P2P_ATTR_DEVICE_ID\n", __FUNCTION__);
5159
if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5160
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5161
break;
5162
}
5163
} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5164
/* Handle the P2P Device Info attribute of probe response */
5165
printk("[%s] P2P_ATTR_DEVICE_INFO\n", __FUNCTION__);
5166
if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5167
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5168
break;
5169
}
5170
}
5171
5172
}
5173
5174
plist = get_next(plist);
5175
5176
}
5177
5178
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5179
printk("[%s] channel = %d\n", __FUNCTION__, uintPeerChannel);
5180
5181
if (uintPeerChannel) {
5182
u8 *wfd_ie;
5183
uint wfd_ielen = 0;
5184
5185
wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5186
if (wfd_ie) {
5187
u8 *wfd_devinfo;
5188
uint wfd_devlen;
5189
5190
RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5191
wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5192
if (wfd_devinfo) {
5193
u16 wfd_devinfo_field = 0;
5194
5195
/* Commented by Albert 20120319 */
5196
/* The first two bytes are the WFD device information field of WFD device information subelement. */
5197
/* In big endian format. */
5198
wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5199
if (wfd_devinfo_field & WFD_DEVINFO_PC_TDLS)
5200
pwfd_info->wfd_pc = _TRUE;
5201
else
5202
pwfd_info->wfd_pc = _FALSE;
5203
}
5204
}
5205
} else
5206
RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5207
5208
return ret;
5209
5210
}
5211
5212
static int rtw_p2p_set_wfd_device_type(struct net_device *dev,
5213
struct iw_request_info *info,
5214
union iwreq_data *wrqu, char *extra)
5215
{
5216
5217
int ret = 0;
5218
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5219
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5220
struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5221
5222
/* Commented by Albert 20120328 */
5223
/* The input data is 0 or 1 */
5224
/* 0: specify to Miracast source device */
5225
/* 1 or others: specify to Miracast sink device (display device) */
5226
5227
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5228
5229
if (extra[0] == '0') /* Set to Miracast source device. */
5230
pwfd_info->wfd_device_type = WFD_DEVINFO_SOURCE;
5231
else /* Set to Miracast sink device. */
5232
pwfd_info->wfd_device_type = WFD_DEVINFO_PSINK;
5233
5234
return ret;
5235
5236
}
5237
5238
static int rtw_p2p_set_wfd_enable(struct net_device *dev,
5239
struct iw_request_info *info,
5240
union iwreq_data *wrqu, char *extra)
5241
{
5242
/* Commented by Kurt 20121206
5243
* This function is used to set wfd enabled */
5244
5245
int ret = 0;
5246
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5247
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5248
5249
if (*extra == '0')
5250
rtw_wfd_enable(padapter, 0);
5251
else if (*extra == '1')
5252
rtw_wfd_enable(padapter, 1);
5253
5254
RTW_INFO("[%s] wfd_enable = %d\n", __FUNCTION__, pwdinfo->wfd_info->wfd_enable);
5255
5256
return ret;
5257
5258
}
5259
5260
static int rtw_p2p_set_driver_iface(struct net_device *dev,
5261
struct iw_request_info *info,
5262
union iwreq_data *wrqu, char *extra)
5263
{
5264
/* Commented by Kurt 20121206
5265
* This function is used to set driver iface is WEXT or CFG80211 */
5266
int ret = 0;
5267
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5268
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5269
5270
if (*extra == '1') {
5271
pwdinfo->driver_interface = DRIVER_WEXT;
5272
RTW_INFO("[%s] driver_interface = WEXT\n", __FUNCTION__);
5273
} else if (*extra == '2') {
5274
pwdinfo->driver_interface = DRIVER_CFG80211;
5275
RTW_INFO("[%s] driver_interface = CFG80211\n", __FUNCTION__);
5276
}
5277
5278
return ret;
5279
5280
}
5281
5282
/* To set the WFD session available to enable or disable */
5283
static int rtw_p2p_set_sa(struct net_device *dev,
5284
struct iw_request_info *info,
5285
union iwreq_data *wrqu, char *extra)
5286
{
5287
5288
int ret = 0;
5289
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5290
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5291
5292
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5293
5294
if (0) {
5295
RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5296
return ret;
5297
} else {
5298
if (extra[0] == '0') /* Disable the session available. */
5299
pwdinfo->session_available = _FALSE;
5300
else if (extra[0] == '1') /* Enable the session available. */
5301
pwdinfo->session_available = _TRUE;
5302
else
5303
pwdinfo->session_available = _FALSE;
5304
}
5305
printk("[%s] session available = %d\n", __FUNCTION__, pwdinfo->session_available);
5306
5307
return ret;
5308
5309
}
5310
#endif /* CONFIG_WFD */
5311
5312
static int rtw_p2p_prov_disc(struct net_device *dev,
5313
struct iw_request_info *info,
5314
union iwreq_data *wrqu, char *extra)
5315
{
5316
int ret = 0;
5317
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5318
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5319
u8 peerMAC[ETH_ALEN] = { 0x00 };
5320
int jj, kk;
5321
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
5322
_list *plist, *phead;
5323
_queue *queue = &(pmlmepriv->scanned_queue);
5324
struct wlan_network *pnetwork = NULL;
5325
uint uintPeerChannel = 0;
5326
u8 attr_content[100] = { 0x00 };
5327
u8 *p2pie;
5328
uint p2pielen = 0, attr_contentlen = 0;
5329
_irqL irqL;
5330
5331
/* Commented by Albert 20110301 */
5332
/* The input data contains two informations. */
5333
/* 1. First information is the MAC address which wants to issue the provisioning discovery request frame. */
5334
/* 2. Second information is the WPS configuration method which wants to discovery */
5335
/* Format: 00:E0:4C:00:00:05_display */
5336
/* Format: 00:E0:4C:00:00:05_keypad */
5337
/* Format: 00:E0:4C:00:00:05_pbc */
5338
/* Format: 00:E0:4C:00:00:05_label */
5339
5340
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5341
5342
if (pwdinfo->p2p_state == P2P_STATE_NONE) {
5343
RTW_INFO("[%s] WiFi Direct is disable!\n", __FUNCTION__);
5344
return ret;
5345
} else {
5346
/* Reset the content of struct tx_provdisc_req_info excluded the wps_config_method_request. */
5347
_rtw_memset(pwdinfo->tx_prov_disc_info.peerDevAddr, 0x00, ETH_ALEN);
5348
_rtw_memset(pwdinfo->tx_prov_disc_info.peerIFAddr, 0x00, ETH_ALEN);
5349
_rtw_memset(&pwdinfo->tx_prov_disc_info.ssid, 0x00, sizeof(NDIS_802_11_SSID));
5350
pwdinfo->tx_prov_disc_info.peer_channel_num[0] = 0;
5351
pwdinfo->tx_prov_disc_info.peer_channel_num[1] = 0;
5352
pwdinfo->tx_prov_disc_info.benable = _FALSE;
5353
}
5354
5355
for (jj = 0, kk = 0; jj < ETH_ALEN; jj++, kk += 3)
5356
peerMAC[jj] = key_2char2num(extra[kk], extra[kk + 1]);
5357
5358
if (_rtw_memcmp(&extra[18], "display", 7))
5359
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
5360
else if (_rtw_memcmp(&extra[18], "keypad", 7))
5361
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
5362
else if (_rtw_memcmp(&extra[18], "pbc", 3))
5363
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
5364
else if (_rtw_memcmp(&extra[18], "label", 5))
5365
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
5366
else {
5367
RTW_INFO("[%s] Unknown WPS config methodn", __FUNCTION__);
5368
return ret ;
5369
}
5370
5371
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5372
5373
phead = get_list_head(queue);
5374
plist = get_next(phead);
5375
5376
while (1) {
5377
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
5378
break;
5379
5380
if (uintPeerChannel != 0)
5381
break;
5382
5383
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
5384
5385
/* Commented by Albert 2011/05/18 */
5386
/* Match the device address located in the P2P IE */
5387
/* This is for the case that the P2P device address is not the same as the P2P interface address. */
5388
5389
p2pie = rtw_bss_ex_get_p2p_ie(&pnetwork->network, NULL, &p2pielen);
5390
if (p2pie) {
5391
while (p2pie) {
5392
/* The P2P Device ID attribute is included in the Beacon frame. */
5393
/* The P2P Device Info attribute is included in the probe response frame. */
5394
5395
if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_ID, attr_content, &attr_contentlen)) {
5396
/* Handle the P2P Device ID attribute of Beacon first */
5397
if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5398
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5399
break;
5400
}
5401
} else if (rtw_get_p2p_attr_content(p2pie, p2pielen, P2P_ATTR_DEVICE_INFO, attr_content, &attr_contentlen)) {
5402
/* Handle the P2P Device Info attribute of probe response */
5403
if (_rtw_memcmp(attr_content, peerMAC, ETH_ALEN)) {
5404
uintPeerChannel = pnetwork->network.Configuration.DSConfig;
5405
break;
5406
}
5407
}
5408
5409
/* Get the next P2P IE */
5410
p2pie = rtw_get_p2p_ie(p2pie + p2pielen, BSS_EX_TLV_IES_LEN(&pnetwork->network) - (p2pie + p2pielen - BSS_EX_TLV_IES(&pnetwork->network)), NULL, &p2pielen);
5411
}
5412
5413
}
5414
5415
plist = get_next(plist);
5416
5417
}
5418
5419
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
5420
5421
if (uintPeerChannel) {
5422
#ifdef CONFIG_WFD
5423
if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5424
struct wifi_display_info *pwfd_info = pwdinfo->wfd_info;
5425
u8 *wfd_ie;
5426
uint wfd_ielen = 0;
5427
5428
wfd_ie = rtw_bss_ex_get_wfd_ie(&pnetwork->network, NULL, &wfd_ielen);
5429
if (wfd_ie) {
5430
u8 *wfd_devinfo;
5431
uint wfd_devlen;
5432
5433
RTW_INFO("[%s] Found WFD IE!\n", __FUNCTION__);
5434
wfd_devinfo = rtw_get_wfd_attr_content(wfd_ie, wfd_ielen, WFD_ATTR_DEVICE_INFO, NULL, &wfd_devlen);
5435
if (wfd_devinfo) {
5436
u16 wfd_devinfo_field = 0;
5437
5438
/* Commented by Albert 20120319 */
5439
/* The first two bytes are the WFD device information field of WFD device information subelement. */
5440
/* In big endian format. */
5441
wfd_devinfo_field = RTW_GET_BE16(wfd_devinfo);
5442
if (wfd_devinfo_field & WFD_DEVINFO_SESSION_AVAIL)
5443
pwfd_info->peer_session_avail = _TRUE;
5444
else
5445
pwfd_info->peer_session_avail = _FALSE;
5446
}
5447
}
5448
5449
if (_FALSE == pwfd_info->peer_session_avail) {
5450
RTW_INFO("[%s] WFD Session not avaiable!\n", __FUNCTION__);
5451
goto exit;
5452
}
5453
}
5454
#endif /* CONFIG_WFD */
5455
5456
RTW_INFO("[%s] peer channel: %d!\n", __FUNCTION__, uintPeerChannel);
5457
#ifdef CONFIG_CONCURRENT_MODE
5458
if (rtw_mi_check_status(padapter, MI_LINKED))
5459
_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
5460
#endif /* CONFIG_CONCURRENT_MODE */
5461
_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, pnetwork->network.MacAddress, ETH_ALEN);
5462
_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, peerMAC, ETH_ALEN);
5463
pwdinfo->tx_prov_disc_info.peer_channel_num[0] = (u16) uintPeerChannel;
5464
pwdinfo->tx_prov_disc_info.benable = _TRUE;
5465
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
5466
rtw_p2p_set_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ);
5467
5468
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT))
5469
_rtw_memcpy(&pwdinfo->tx_prov_disc_info.ssid, &pnetwork->network.Ssid, sizeof(NDIS_802_11_SSID));
5470
else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5471
_rtw_memcpy(pwdinfo->tx_prov_disc_info.ssid.Ssid, pwdinfo->p2p_wildcard_ssid, P2P_WILDCARD_SSID_LEN);
5472
pwdinfo->tx_prov_disc_info.ssid.SsidLength = P2P_WILDCARD_SSID_LEN;
5473
}
5474
5475
#ifdef CONFIG_CONCURRENT_MODE
5476
if (rtw_mi_check_status(padapter, MI_LINKED)) {
5477
u8 union_ch = rtw_mi_get_union_chan(padapter);
5478
u8 union_bw = rtw_mi_get_union_bw(padapter);
5479
u8 union_offset = rtw_mi_get_union_offset(padapter);
5480
5481
set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
5482
rtw_leave_opch(padapter);
5483
5484
} else
5485
set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5486
#else
5487
set_channel_bwmode(padapter, uintPeerChannel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
5488
#endif
5489
5490
_set_timer(&pwdinfo->pre_tx_scan_timer, P2P_TX_PRESCAN_TIMEOUT);
5491
5492
#ifdef CONFIG_CONCURRENT_MODE
5493
if (rtw_mi_check_status(padapter, MI_LINKED))
5494
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_CONCURRENT_PROVISION_TIMEOUT);
5495
else
5496
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
5497
#else
5498
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
5499
#endif /* CONFIG_CONCURRENT_MODE */
5500
5501
} else {
5502
RTW_INFO("[%s] NOT Found in the Scanning Queue!\n", __FUNCTION__);
5503
}
5504
exit:
5505
5506
return ret;
5507
5508
}
5509
5510
/* Added by Albert 20110328
5511
* This function is used to inform the driver the user had specified the pin code value or pbc
5512
* to application. */
5513
5514
static int rtw_p2p_got_wpsinfo(struct net_device *dev,
5515
struct iw_request_info *info,
5516
union iwreq_data *wrqu, char *extra)
5517
{
5518
5519
int ret = 0;
5520
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5521
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5522
5523
5524
RTW_INFO("[%s] data = %s\n", __FUNCTION__, extra);
5525
/* Added by Albert 20110328 */
5526
/* if the input data is P2P_NO_WPSINFO -> reset the wpsinfo */
5527
/* if the input data is P2P_GOT_WPSINFO_PEER_DISPLAY_PIN -> the utility just input the PIN code got from the peer P2P device. */
5528
/* if the input data is P2P_GOT_WPSINFO_SELF_DISPLAY_PIN -> the utility just got the PIN code from itself. */
5529
/* if the input data is P2P_GOT_WPSINFO_PBC -> the utility just determine to use the PBC */
5530
5531
if (*extra == '0')
5532
pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5533
else if (*extra == '1')
5534
pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PEER_DISPLAY_PIN;
5535
else if (*extra == '2')
5536
pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_SELF_DISPLAY_PIN;
5537
else if (*extra == '3')
5538
pwdinfo->ui_got_wps_info = P2P_GOT_WPSINFO_PBC;
5539
else
5540
pwdinfo->ui_got_wps_info = P2P_NO_WPSINFO;
5541
5542
return ret;
5543
5544
}
5545
5546
#endif /* CONFIG_P2P */
5547
5548
static int rtw_p2p_set(struct net_device *dev,
5549
struct iw_request_info *info,
5550
union iwreq_data *wrqu, char *extra)
5551
{
5552
int ret = 0;
5553
#ifdef CONFIG_P2P
5554
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5555
5556
RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
5557
5558
if (_rtw_memcmp(extra, "enable=", 7))
5559
rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
5560
else if (_rtw_memcmp(extra, "setDN=", 6)) {
5561
wrqu->data.length -= 6;
5562
rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
5563
} else if (_rtw_memcmp(extra, "profilefound=", 13)) {
5564
wrqu->data.length -= 13;
5565
rtw_p2p_profilefound(dev, info, wrqu, &extra[13]);
5566
} else if (_rtw_memcmp(extra, "prov_disc=", 10)) {
5567
wrqu->data.length -= 10;
5568
rtw_p2p_prov_disc(dev, info, wrqu, &extra[10]);
5569
} else if (_rtw_memcmp(extra, "nego=", 5)) {
5570
wrqu->data.length -= 5;
5571
rtw_p2p_connect(dev, info, wrqu, &extra[5]);
5572
} else if (_rtw_memcmp(extra, "intent=", 7)) {
5573
/* Commented by Albert 2011/03/23 */
5574
/* The wrqu->data.length will include the null character */
5575
/* So, we will decrease 7 + 1 */
5576
wrqu->data.length -= 8;
5577
rtw_p2p_set_intent(dev, info, wrqu, &extra[7]);
5578
} else if (_rtw_memcmp(extra, "ssid=", 5)) {
5579
wrqu->data.length -= 5;
5580
rtw_p2p_set_go_nego_ssid(dev, info, wrqu, &extra[5]);
5581
} else if (_rtw_memcmp(extra, "got_wpsinfo=", 12)) {
5582
wrqu->data.length -= 12;
5583
rtw_p2p_got_wpsinfo(dev, info, wrqu, &extra[12]);
5584
} else if (_rtw_memcmp(extra, "listen_ch=", 10)) {
5585
/* Commented by Albert 2011/05/24 */
5586
/* The wrqu->data.length will include the null character */
5587
/* So, we will decrease (10 + 1) */
5588
wrqu->data.length -= 11;
5589
rtw_p2p_set_listen_ch(dev, info, wrqu, &extra[10]);
5590
} else if (_rtw_memcmp(extra, "op_ch=", 6)) {
5591
/* Commented by Albert 2011/05/24 */
5592
/* The wrqu->data.length will include the null character */
5593
/* So, we will decrease (6 + 1) */
5594
wrqu->data.length -= 7;
5595
rtw_p2p_set_op_ch(dev, info, wrqu, &extra[6]);
5596
} else if (_rtw_memcmp(extra, "invite=", 7)) {
5597
wrqu->data.length -= 8;
5598
rtw_p2p_invite_req(dev, info, wrqu, &extra[7]);
5599
} else if (_rtw_memcmp(extra, "persistent=", 11)) {
5600
wrqu->data.length -= 11;
5601
rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
5602
} else if (_rtw_memcmp(extra, "uuid=", 5)) {
5603
wrqu->data.length -= 5;
5604
ret = rtw_p2p_set_wps_uuid(dev, info, wrqu, &extra[5]);
5605
}
5606
5607
#ifdef CONFIG_WFD
5608
if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5609
if (_rtw_memcmp(extra, "sa=", 3)) {
5610
/* sa: WFD Session Available information */
5611
wrqu->data.length -= 3;
5612
rtw_p2p_set_sa(dev, info, wrqu, &extra[3]);
5613
} else if (_rtw_memcmp(extra, "pc=", 3)) {
5614
/* pc: WFD Preferred Connection */
5615
wrqu->data.length -= 3;
5616
rtw_p2p_set_pc(dev, info, wrqu, &extra[3]);
5617
} else if (_rtw_memcmp(extra, "wfd_type=", 9)) {
5618
wrqu->data.length -= 9;
5619
rtw_p2p_set_wfd_device_type(dev, info, wrqu, &extra[9]);
5620
} else if (_rtw_memcmp(extra, "wfd_enable=", 11)) {
5621
wrqu->data.length -= 11;
5622
rtw_p2p_set_wfd_enable(dev, info, wrqu, &extra[11]);
5623
} else if (_rtw_memcmp(extra, "driver_iface=", 13)) {
5624
wrqu->data.length -= 13;
5625
rtw_p2p_set_driver_iface(dev, info, wrqu, &extra[13]);
5626
}
5627
}
5628
#endif /* CONFIG_WFD */
5629
5630
#endif /* CONFIG_P2P */
5631
5632
return ret;
5633
5634
}
5635
5636
static int rtw_p2p_get(struct net_device *dev,
5637
struct iw_request_info *info,
5638
union iwreq_data *wrqu, char *extra)
5639
{
5640
int ret = 0;
5641
#ifdef CONFIG_P2P
5642
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5643
5644
if (padapter->bShowGetP2PState)
5645
RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
5646
5647
if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
5648
rtw_p2p_get_status(dev, info, wrqu, extra);
5649
else if (_rtw_memcmp(wrqu->data.pointer, "role", 4))
5650
rtw_p2p_get_role(dev, info, wrqu, extra);
5651
else if (_rtw_memcmp(wrqu->data.pointer, "peer_ifa", 8))
5652
rtw_p2p_get_peer_ifaddr(dev, info, wrqu, extra);
5653
else if (_rtw_memcmp(wrqu->data.pointer, "req_cm", 6))
5654
rtw_p2p_get_req_cm(dev, info, wrqu, extra);
5655
else if (_rtw_memcmp(wrqu->data.pointer, "peer_deva", 9)) {
5656
/* Get the P2P device address when receiving the provision discovery request frame. */
5657
rtw_p2p_get_peer_devaddr(dev, info, wrqu, extra);
5658
} else if (_rtw_memcmp(wrqu->data.pointer, "group_id", 8))
5659
rtw_p2p_get_groupid(dev, info, wrqu, extra);
5660
else if (_rtw_memcmp(wrqu->data.pointer, "inv_peer_deva", 13)) {
5661
/* Get the P2P device address when receiving the P2P Invitation request frame. */
5662
rtw_p2p_get_peer_devaddr_by_invitation(dev, info, wrqu, extra);
5663
} else if (_rtw_memcmp(wrqu->data.pointer, "op_ch", 5))
5664
rtw_p2p_get_op_ch(dev, info, wrqu, extra);
5665
5666
#ifdef CONFIG_WFD
5667
if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
5668
if (_rtw_memcmp(wrqu->data.pointer, "peer_port", 9))
5669
rtw_p2p_get_peer_wfd_port(dev, info, wrqu, extra);
5670
else if (_rtw_memcmp(wrqu->data.pointer, "wfd_sa", 6))
5671
rtw_p2p_get_peer_wfd_session_available(dev, info, wrqu, extra);
5672
else if (_rtw_memcmp(wrqu->data.pointer, "wfd_pc", 6))
5673
rtw_p2p_get_peer_wfd_preferred_connection(dev, info, wrqu, extra);
5674
}
5675
#endif /* CONFIG_WFD */
5676
5677
#endif /* CONFIG_P2P */
5678
5679
return ret;
5680
5681
}
5682
5683
static int rtw_p2p_get2(struct net_device *dev,
5684
struct iw_request_info *info,
5685
union iwreq_data *wrqu, char *extra)
5686
{
5687
5688
int ret = 0;
5689
5690
#ifdef CONFIG_P2P
5691
5692
int length = wrqu->data.length;
5693
char *buffer = (u8 *)rtw_malloc(length);
5694
5695
if (buffer == NULL) {
5696
ret = -ENOMEM;
5697
goto bad;
5698
}
5699
5700
if (copy_from_user(buffer, wrqu->data.pointer, wrqu->data.length)) {
5701
ret = -EFAULT;
5702
goto bad;
5703
}
5704
5705
RTW_INFO("[%s] buffer = %s\n", __FUNCTION__, buffer);
5706
5707
if (_rtw_memcmp(buffer, "wpsCM=", 6))
5708
ret = rtw_p2p_get_wps_configmethod(dev, info, wrqu, extra, &buffer[6]);
5709
else if (_rtw_memcmp(buffer, "devN=", 5))
5710
ret = rtw_p2p_get_device_name(dev, info, wrqu, extra, &buffer[5]);
5711
else if (_rtw_memcmp(buffer, "dev_type=", 9))
5712
ret = rtw_p2p_get_device_type(dev, info, wrqu, extra, &buffer[9]);
5713
else if (_rtw_memcmp(buffer, "go_devadd=", 10))
5714
ret = rtw_p2p_get_go_device_address(dev, info, wrqu, extra, &buffer[10]);
5715
else if (_rtw_memcmp(buffer, "InvProc=", 8))
5716
ret = rtw_p2p_get_invitation_procedure(dev, info, wrqu, extra, &buffer[8]);
5717
else {
5718
snprintf(extra, sizeof("Command not found."), "Command not found.");
5719
wrqu->data.length = strlen(extra);
5720
}
5721
5722
bad:
5723
if (buffer)
5724
rtw_mfree(buffer, length);
5725
5726
#endif /* CONFIG_P2P */
5727
5728
return ret;
5729
5730
}
5731
5732
#ifdef CONFIG_MP_INCLUDED
5733
static int rtw_cta_test_start(struct net_device *dev,
5734
struct iw_request_info *info,
5735
union iwreq_data *wrqu, char *extra)
5736
{
5737
int ret = 0;
5738
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5739
HAL_DATA_TYPE *hal_data = GET_HAL_DATA(padapter);
5740
5741
RTW_INFO("%s %s\n", __func__, extra);
5742
if (!strcmp(extra, "1"))
5743
hal_data->in_cta_test = 1;
5744
else
5745
hal_data->in_cta_test = 0;
5746
5747
rtw_hal_rcr_set_chk_bssid(padapter, MLME_ACTION_NONE);
5748
5749
return ret;
5750
}
5751
#endif
5752
extern int rtw_change_ifname(_adapter *padapter, const char *ifname);
5753
static int rtw_rereg_nd_name(struct net_device *dev,
5754
struct iw_request_info *info,
5755
union iwreq_data *wrqu, char *extra)
5756
{
5757
int ret = 0;
5758
_adapter *padapter = rtw_netdev_priv(dev);
5759
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
5760
struct rereg_nd_name_data *rereg_priv = &padapter->rereg_nd_name_priv;
5761
char new_ifname[IFNAMSIZ];
5762
5763
if (rereg_priv->old_ifname[0] == 0) {
5764
char *reg_ifname;
5765
#ifdef CONFIG_CONCURRENT_MODE
5766
if (padapter->isprimary)
5767
reg_ifname = padapter->registrypriv.ifname;
5768
else
5769
#endif
5770
reg_ifname = padapter->registrypriv.if2name;
5771
5772
strncpy(rereg_priv->old_ifname, reg_ifname, IFNAMSIZ);
5773
rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
5774
}
5775
5776
/* RTW_INFO("%s wrqu->data.length:%d\n", __FUNCTION__, wrqu->data.length); */
5777
if (wrqu->data.length > IFNAMSIZ)
5778
return -EFAULT;
5779
5780
if (copy_from_user(new_ifname, wrqu->data.pointer, IFNAMSIZ))
5781
return -EFAULT;
5782
5783
if (0 == strcmp(rereg_priv->old_ifname, new_ifname))
5784
return ret;
5785
5786
RTW_INFO("%s new_ifname:%s\n", __FUNCTION__, new_ifname);
5787
rtw_set_rtnl_lock_holder(dvobj, current);
5788
ret = rtw_change_ifname(padapter, new_ifname);
5789
rtw_set_rtnl_lock_holder(dvobj, NULL);
5790
if (0 != ret)
5791
goto exit;
5792
5793
if (_rtw_memcmp(rereg_priv->old_ifname, "disable%d", 9) == _TRUE) {
5794
/* rtw_ips_mode_req(&padapter->pwrctrlpriv, rereg_priv->old_ips_mode); */
5795
}
5796
5797
strncpy(rereg_priv->old_ifname, new_ifname, IFNAMSIZ);
5798
rereg_priv->old_ifname[IFNAMSIZ - 1] = 0;
5799
5800
if (_rtw_memcmp(new_ifname, "disable%d", 9) == _TRUE) {
5801
5802
RTW_INFO("%s disable\n", __FUNCTION__);
5803
/* free network queue for Android's timming issue */
5804
rtw_free_network_queue(padapter, _TRUE);
5805
5806
/* the interface is being "disabled", we can do deeper IPS */
5807
/* rereg_priv->old_ips_mode = rtw_get_ips_mode_req(&padapter->pwrctrlpriv); */
5808
/* rtw_ips_mode_req(&padapter->pwrctrlpriv, IPS_NORMAL); */
5809
}
5810
exit:
5811
return ret;
5812
5813
}
5814
5815
#ifdef CONFIG_IOL
5816
#include <rtw_iol.h>
5817
#endif
5818
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
5819
#include "../../hal/hal_dm_acs.h"
5820
#endif
5821
#ifdef DBG_CMD_QUEUE
5822
u8 dump_cmd_id = 0;
5823
#endif
5824
5825
static int rtw_dbg_port(struct net_device *dev,
5826
struct iw_request_info *info,
5827
union iwreq_data *wrqu, char *extra)
5828
{
5829
_irqL irqL;
5830
int ret = 0;
5831
u8 major_cmd, minor_cmd;
5832
u16 arg;
5833
u32 extra_arg, *pdata, val32;
5834
struct sta_info *psta;
5835
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
5836
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5837
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5838
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5839
struct security_priv *psecuritypriv = &padapter->securitypriv;
5840
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
5841
struct sta_priv *pstapriv = &padapter->stapriv;
5842
5843
5844
pdata = (u32 *)&wrqu->data;
5845
5846
val32 = *pdata;
5847
arg = (u16)(val32 & 0x0000ffff);
5848
major_cmd = (u8)(val32 >> 24);
5849
minor_cmd = (u8)((val32 >> 16) & 0x00ff);
5850
5851
extra_arg = *(pdata + 1);
5852
5853
switch (major_cmd) {
5854
case 0x70: /* read_reg */
5855
switch (minor_cmd) {
5856
case 1:
5857
RTW_INFO("rtw_read8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5858
break;
5859
case 2:
5860
RTW_INFO("rtw_read16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5861
break;
5862
case 4:
5863
RTW_INFO("rtw_read32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5864
break;
5865
}
5866
break;
5867
case 0x71: /* write_reg */
5868
switch (minor_cmd) {
5869
case 1:
5870
rtw_write8(padapter, arg, extra_arg);
5871
RTW_INFO("rtw_write8(0x%x)=0x%02x\n", arg, rtw_read8(padapter, arg));
5872
break;
5873
case 2:
5874
rtw_write16(padapter, arg, extra_arg);
5875
RTW_INFO("rtw_write16(0x%x)=0x%04x\n", arg, rtw_read16(padapter, arg));
5876
break;
5877
case 4:
5878
rtw_write32(padapter, arg, extra_arg);
5879
RTW_INFO("rtw_write32(0x%x)=0x%08x\n", arg, rtw_read32(padapter, arg));
5880
break;
5881
}
5882
break;
5883
case 0x72: /* read_bb */
5884
RTW_INFO("read_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5885
break;
5886
case 0x73: /* write_bb */
5887
rtw_hal_write_bbreg(padapter, arg, 0xffffffff, extra_arg);
5888
RTW_INFO("write_bbreg(0x%x)=0x%x\n", arg, rtw_hal_read_bbreg(padapter, arg, 0xffffffff));
5889
break;
5890
case 0x74: /* read_rf */
5891
RTW_INFO("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));
5892
break;
5893
case 0x75: /* write_rf */
5894
rtw_hal_write_rfreg(padapter, minor_cmd, arg, 0xffffffff, extra_arg);
5895
RTW_INFO("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));
5896
break;
5897
5898
case 0x76:
5899
switch (minor_cmd) {
5900
case 0x00: /* normal mode, */
5901
padapter->recvpriv.is_signal_dbg = 0;
5902
break;
5903
case 0x01: /* dbg mode */
5904
padapter->recvpriv.is_signal_dbg = 1;
5905
extra_arg = extra_arg > 100 ? 100 : extra_arg;
5906
padapter->recvpriv.signal_strength_dbg = extra_arg;
5907
break;
5908
}
5909
break;
5910
case 0x78: /* IOL test */
5911
switch (minor_cmd) {
5912
#ifdef CONFIG_IOL
5913
case 0x04: { /* LLT table initialization test */
5914
u8 page_boundary = 0xf9;
5915
{
5916
struct xmit_frame *xmit_frame;
5917
5918
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5919
if (xmit_frame == NULL) {
5920
ret = -ENOMEM;
5921
break;
5922
}
5923
5924
rtw_IOL_append_LLT_cmd(xmit_frame, page_boundary);
5925
5926
5927
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 500, 0))
5928
ret = -EPERM;
5929
}
5930
}
5931
break;
5932
case 0x05: { /* blink LED test */
5933
u16 reg = 0x4c;
5934
u32 blink_num = 50;
5935
u32 blink_delay_ms = 200;
5936
int i;
5937
5938
{
5939
struct xmit_frame *xmit_frame;
5940
5941
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5942
if (xmit_frame == NULL) {
5943
ret = -ENOMEM;
5944
break;
5945
}
5946
5947
for (i = 0; i < blink_num; i++) {
5948
#ifdef CONFIG_IOL_NEW_GENERATION
5949
rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00, 0xff);
5950
rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5951
rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08, 0xff);
5952
rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5953
#else
5954
rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x00);
5955
rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5956
rtw_IOL_append_WB_cmd(xmit_frame, reg, 0x08);
5957
rtw_IOL_append_DELAY_MS_cmd(xmit_frame, blink_delay_ms);
5958
#endif
5959
}
5960
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, (blink_delay_ms * blink_num * 2) + 200, 0))
5961
ret = -EPERM;
5962
}
5963
}
5964
break;
5965
5966
case 0x06: { /* continuous wirte byte test */
5967
u16 reg = arg;
5968
u16 start_value = 0;
5969
u32 write_num = extra_arg;
5970
int i;
5971
u8 final;
5972
5973
{
5974
struct xmit_frame *xmit_frame;
5975
5976
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
5977
if (xmit_frame == NULL) {
5978
ret = -ENOMEM;
5979
break;
5980
}
5981
5982
for (i = 0; i < write_num; i++) {
5983
#ifdef CONFIG_IOL_NEW_GENERATION
5984
rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value, 0xFF);
5985
#else
5986
rtw_IOL_append_WB_cmd(xmit_frame, reg, i + start_value);
5987
#endif
5988
}
5989
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
5990
ret = -EPERM;
5991
}
5992
5993
final = rtw_read8(padapter, reg);
5994
if (start_value + write_num - 1 == final)
5995
RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
5996
else
5997
RTW_INFO("continuous IOL_CMD_WB_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
5998
}
5999
break;
6000
6001
case 0x07: { /* continuous wirte word test */
6002
u16 reg = arg;
6003
u16 start_value = 200;
6004
u32 write_num = extra_arg;
6005
6006
int i;
6007
u16 final;
6008
6009
{
6010
struct xmit_frame *xmit_frame;
6011
6012
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6013
if (xmit_frame == NULL) {
6014
ret = -ENOMEM;
6015
break;
6016
}
6017
6018
for (i = 0; i < write_num; i++) {
6019
#ifdef CONFIG_IOL_NEW_GENERATION
6020
rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value, 0xFFFF);
6021
#else
6022
rtw_IOL_append_WW_cmd(xmit_frame, reg, i + start_value);
6023
#endif
6024
}
6025
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6026
ret = -EPERM;
6027
}
6028
6029
final = rtw_read16(padapter, reg);
6030
if (start_value + write_num - 1 == final)
6031
RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6032
else
6033
RTW_INFO("continuous IOL_CMD_WW_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6034
}
6035
break;
6036
6037
case 0x08: { /* continuous wirte dword test */
6038
u16 reg = arg;
6039
u32 start_value = 0x110000c7;
6040
u32 write_num = extra_arg;
6041
6042
int i;
6043
u32 final;
6044
6045
{
6046
struct xmit_frame *xmit_frame;
6047
6048
xmit_frame = rtw_IOL_accquire_xmit_frame(padapter);
6049
if (xmit_frame == NULL) {
6050
ret = -ENOMEM;
6051
break;
6052
}
6053
6054
for (i = 0; i < write_num; i++) {
6055
#ifdef CONFIG_IOL_NEW_GENERATION
6056
rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value, 0xFFFFFFFF);
6057
#else
6058
rtw_IOL_append_WD_cmd(xmit_frame, reg, i + start_value);
6059
#endif
6060
}
6061
if (_SUCCESS != rtw_IOL_exec_cmds_sync(padapter, xmit_frame, 5000, 0))
6062
ret = -EPERM;
6063
6064
}
6065
6066
final = rtw_read32(padapter, reg);
6067
if (start_value + write_num - 1 == final)
6068
RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Success, start:%u, final:%u\n", reg, write_num, start_value, final);
6069
else
6070
RTW_INFO("continuous IOL_CMD_WD_REG to 0x%x %u times Fail, start:%u, final:%u\n", reg, write_num, start_value, final);
6071
}
6072
break;
6073
#endif /* CONFIG_IOL */
6074
}
6075
break;
6076
case 0x79: {
6077
/*
6078
* dbg 0x79000000 [value], set RESP_TXAGC to + value, value:0~15
6079
* dbg 0x79010000 [value], set RESP_TXAGC to - value, value:0~15
6080
*/
6081
u8 value = extra_arg & 0x0f;
6082
u8 sign = minor_cmd;
6083
u16 write_value = 0;
6084
6085
RTW_INFO("%s set RESP_TXAGC to %s %u\n", __func__, sign ? "minus" : "plus", value);
6086
6087
if (sign)
6088
value = value | 0x10;
6089
6090
write_value = value | (value << 5);
6091
rtw_write16(padapter, 0x6d9, write_value);
6092
}
6093
break;
6094
case 0x7a:
6095
receive_disconnect(padapter, pmlmeinfo->network.MacAddress
6096
, WLAN_REASON_EXPIRATION_CHK, _FALSE);
6097
break;
6098
case 0x7F:
6099
switch (minor_cmd) {
6100
case 0x0:
6101
RTW_INFO("fwstate=0x%x\n", get_fwstate(pmlmepriv));
6102
break;
6103
case 0x01:
6104
RTW_INFO("auth_alg=0x%x, enc_alg=0x%x, auth_type=0x%x, enc_type=0x%x\n",
6105
psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
6106
psecuritypriv->ndisauthtype, psecuritypriv->ndisencryptstatus);
6107
break;
6108
case 0x03:
6109
RTW_INFO("qos_option=%d\n", pmlmepriv->qospriv.qos_option);
6110
#ifdef CONFIG_80211N_HT
6111
RTW_INFO("ht_option=%d\n", pmlmepriv->htpriv.ht_option);
6112
#endif /* CONFIG_80211N_HT */
6113
break;
6114
case 0x04:
6115
RTW_INFO("cur_ch=%d\n", pmlmeext->cur_channel);
6116
RTW_INFO("cur_bw=%d\n", pmlmeext->cur_bwmode);
6117
RTW_INFO("cur_ch_off=%d\n", pmlmeext->cur_ch_offset);
6118
6119
RTW_INFO("oper_ch=%d\n", rtw_get_oper_ch(padapter));
6120
RTW_INFO("oper_bw=%d\n", rtw_get_oper_bw(padapter));
6121
RTW_INFO("oper_ch_offet=%d\n", rtw_get_oper_choffset(padapter));
6122
6123
break;
6124
case 0x05:
6125
psta = rtw_get_stainfo(pstapriv, cur_network->network.MacAddress);
6126
if (psta) {
6127
RTW_INFO("SSID=%s\n", cur_network->network.Ssid.Ssid);
6128
RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
6129
RTW_INFO("cur_channel=%d, cur_bwmode=%d, cur_ch_offset=%d\n", pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset);
6130
RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6131
RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",
6132
psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);
6133
#ifdef CONFIG_80211N_HT
6134
RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6135
RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n"
6136
, psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m, psta->htpriv.sgi_40m);
6137
RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6138
RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6139
#endif /* CONFIG_80211N_HT */
6140
6141
sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6142
} else
6143
RTW_INFO("can't get sta's macaddr, cur_network's macaddr:" MAC_FMT "\n", MAC_ARG(cur_network->network.MacAddress));
6144
break;
6145
case 0x06: {
6146
u64 tsf = 0;
6147
6148
tsf = rtw_hal_get_tsftr_by_port(padapter, extra_arg);
6149
RTW_INFO(" PORT-%d TSF :%21lld\n", extra_arg, tsf);
6150
}
6151
break;
6152
case 0x07:
6153
RTW_INFO("bSurpriseRemoved=%s, bDriverStopped=%s\n"
6154
, rtw_is_surprise_removed(padapter) ? "True" : "False"
6155
, rtw_is_drv_stopped(padapter) ? "True" : "False");
6156
break;
6157
case 0x08: {
6158
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
6159
struct recv_priv *precvpriv = &padapter->recvpriv;
6160
6161
RTW_INFO("free_xmitbuf_cnt=%d, free_xmitframe_cnt=%d"
6162
", free_xmit_extbuf_cnt=%d, free_xframe_ext_cnt=%d"
6163
", free_recvframe_cnt=%d\n",
6164
pxmitpriv->free_xmitbuf_cnt, pxmitpriv->free_xmitframe_cnt,
6165
pxmitpriv->free_xmit_extbuf_cnt, pxmitpriv->free_xframe_ext_cnt,
6166
precvpriv->free_recvframe_cnt);
6167
#ifdef CONFIG_USB_HCI
6168
RTW_INFO("rx_urb_pending_cn=%d\n", ATOMIC_READ(&(precvpriv->rx_pending_cnt)));
6169
#endif
6170
}
6171
break;
6172
case 0x09: {
6173
int i;
6174
_list *plist, *phead;
6175
6176
#ifdef CONFIG_AP_MODE
6177
RTW_INFO_DUMP("sta_dz_bitmap:", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len);
6178
RTW_INFO_DUMP("tim_bitmap:", pstapriv->tim_bitmap, pstapriv->aid_bmp_len);
6179
#endif
6180
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6181
6182
for (i = 0; i < NUM_STA; i++) {
6183
phead = &(pstapriv->sta_hash[i]);
6184
plist = get_next(phead);
6185
6186
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
6187
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
6188
6189
plist = get_next(plist);
6190
6191
if (extra_arg == psta->cmn.aid) {
6192
RTW_INFO("sta's macaddr:" MAC_FMT "\n", MAC_ARG(psta->cmn.mac_addr));
6193
RTW_INFO("rtsen=%d, cts2slef=%d\n", psta->rtsen, psta->cts2self);
6194
RTW_INFO("state=0x%x, aid=%d, macid=%d, raid=%d\n",
6195
psta->state, psta->cmn.aid, psta->cmn.mac_id, psta->cmn.ra_info.rate_id);
6196
#ifdef CONFIG_80211N_HT
6197
RTW_INFO("qos_en=%d, ht_en=%d, init_rate=%d\n", psta->qos_option, psta->htpriv.ht_option, psta->init_rate);
6198
RTW_INFO("bwmode=%d, ch_offset=%d, sgi_20m=%d,sgi_40m=%d\n",
6199
psta->cmn.bw_mode, psta->htpriv.ch_offset, psta->htpriv.sgi_20m,
6200
psta->htpriv.sgi_40m);
6201
RTW_INFO("ampdu_enable = %d\n", psta->htpriv.ampdu_enable);
6202
RTW_INFO("agg_enable_bitmap=%x, candidate_tid_bitmap=%x\n", psta->htpriv.agg_enable_bitmap, psta->htpriv.candidate_tid_bitmap);
6203
#endif /* CONFIG_80211N_HT */
6204
6205
#ifdef CONFIG_AP_MODE
6206
RTW_INFO("capability=0x%x\n", psta->capability);
6207
RTW_INFO("flags=0x%x\n", psta->flags);
6208
RTW_INFO("wpa_psk=0x%x\n", psta->wpa_psk);
6209
RTW_INFO("wpa2_group_cipher=0x%x\n", psta->wpa2_group_cipher);
6210
RTW_INFO("wpa2_pairwise_cipher=0x%x\n", psta->wpa2_pairwise_cipher);
6211
RTW_INFO("qos_info=0x%x\n", psta->qos_info);
6212
#endif
6213
RTW_INFO("dot118021XPrivacy=0x%x\n", psta->dot118021XPrivacy);
6214
6215
sta_rx_reorder_ctl_dump(RTW_DBGDUMP, psta);
6216
}
6217
6218
}
6219
}
6220
6221
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
6222
6223
}
6224
break;
6225
6226
case 0x0b: { /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6227
/* u8 driver_vcs_en; */ /* Enable=1, Disable=0 driver control vrtl_carrier_sense. */
6228
/* u8 driver_vcs_type; */ /* force 0:disable VCS, 1:RTS-CTS, 2:CTS-to-self when vcs_en=1. */
6229
6230
if (arg == 0) {
6231
RTW_INFO("disable driver ctrl vcs\n");
6232
padapter->driver_vcs_en = 0;
6233
} else if (arg == 1) {
6234
RTW_INFO("enable driver ctrl vcs = %d\n", extra_arg);
6235
padapter->driver_vcs_en = 1;
6236
6237
if (extra_arg > 2)
6238
padapter->driver_vcs_type = 1;
6239
else
6240
padapter->driver_vcs_type = extra_arg;
6241
}
6242
}
6243
break;
6244
case 0x0c: { /* dump rx/tx packet */
6245
if (arg == 0) {
6246
RTW_INFO("dump rx packet (%d)\n", extra_arg);
6247
/* pHalData->bDumpRxPkt =extra_arg; */
6248
rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_RXPKT, &(extra_arg));
6249
} else if (arg == 1) {
6250
RTW_INFO("dump tx packet (%d)\n", extra_arg);
6251
rtw_hal_set_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(extra_arg));
6252
}
6253
}
6254
break;
6255
case 0x0e: {
6256
if (arg == 0) {
6257
RTW_INFO("disable driver ctrl rx_ampdu_factor\n");
6258
padapter->driver_rx_ampdu_factor = 0xFF;
6259
} else if (arg == 1) {
6260
6261
RTW_INFO("enable driver ctrl rx_ampdu_factor = %d\n", extra_arg);
6262
6263
if (extra_arg > 0x03)
6264
padapter->driver_rx_ampdu_factor = 0xFF;
6265
else
6266
padapter->driver_rx_ampdu_factor = extra_arg;
6267
}
6268
}
6269
break;
6270
#ifdef DBG_CONFIG_ERROR_DETECT
6271
case 0x0f: {
6272
if (extra_arg == 0) {
6273
RTW_INFO("###### silent reset test.......#####\n");
6274
rtw_hal_sreset_reset(padapter);
6275
} else {
6276
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
6277
struct sreset_priv *psrtpriv = &pHalData->srestpriv;
6278
psrtpriv->dbg_trigger_point = extra_arg;
6279
}
6280
6281
}
6282
break;
6283
case 0x15: {
6284
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6285
RTW_INFO("==>silent resete cnts:%d\n", pwrpriv->ips_enter_cnts);
6286
}
6287
break;
6288
6289
#endif
6290
6291
case 0x10: /* driver version display */
6292
dump_drv_version(RTW_DBGDUMP);
6293
break;
6294
case 0x11: { /* dump linked status */
6295
int pre_mode;
6296
pre_mode = padapter->bLinkInfoDump;
6297
/* linked_info_dump(padapter,extra_arg); */
6298
if (extra_arg == 1 || (extra_arg == 0 && pre_mode == 1)) /* not consider pwr_saving 0: */
6299
padapter->bLinkInfoDump = extra_arg;
6300
6301
else if ((extra_arg == 2) || (extra_arg == 0 && pre_mode == 2)) { /* consider power_saving */
6302
/* RTW_INFO("linked_info_dump =%s\n", (padapter->bLinkInfoDump)?"enable":"disable") */
6303
linked_info_dump(padapter, extra_arg);
6304
}
6305
6306
6307
6308
}
6309
break;
6310
#ifdef CONFIG_80211N_HT
6311
case 0x12: { /* set rx_stbc */
6312
struct registry_priv *pregpriv = &padapter->registrypriv;
6313
/* 0: disable, bit(0):enable 2.4g, bit(1):enable 5g, 0x3: enable both 2.4g and 5g */
6314
/* default is set to enable 2.4GHZ for IOT issue with bufflao's AP at 5GHZ */
6315
if (pregpriv && (extra_arg == 0 || extra_arg == 1 || extra_arg == 2 || extra_arg == 3)) {
6316
pregpriv->rx_stbc = extra_arg;
6317
RTW_INFO("set rx_stbc=%d\n", pregpriv->rx_stbc);
6318
} else
6319
RTW_INFO("get rx_stbc=%d\n", pregpriv->rx_stbc);
6320
6321
}
6322
break;
6323
case 0x13: { /* set ampdu_enable */
6324
struct registry_priv *pregpriv = &padapter->registrypriv;
6325
/* 0: disable, 0x1:enable */
6326
if (pregpriv && extra_arg < 2) {
6327
pregpriv->ampdu_enable = extra_arg;
6328
RTW_INFO("set ampdu_enable=%d\n", pregpriv->ampdu_enable);
6329
} else
6330
RTW_INFO("get ampdu_enable=%d\n", pregpriv->ampdu_enable);
6331
6332
}
6333
break;
6334
#endif
6335
case 0x14: { /* get wifi_spec */
6336
struct registry_priv *pregpriv = &padapter->registrypriv;
6337
RTW_INFO("get wifi_spec=%d\n", pregpriv->wifi_spec);
6338
6339
}
6340
break;
6341
6342
#ifdef DBG_FIXED_CHAN
6343
case 0x17: {
6344
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6345
printk("===> Fixed channel to %d\n", extra_arg);
6346
pmlmeext->fixed_chan = extra_arg;
6347
6348
}
6349
break;
6350
#endif
6351
#ifdef CONFIG_80211N_HT
6352
case 0x19: {
6353
struct registry_priv *pregistrypriv = &padapter->registrypriv;
6354
/* extra_arg : */
6355
/* BIT0: Enable VHT LDPC Rx, BIT1: Enable VHT LDPC Tx, */
6356
/* BIT4: Enable HT LDPC Rx, BIT5: Enable HT LDPC Tx */
6357
if (arg == 0) {
6358
RTW_INFO("driver disable LDPC\n");
6359
pregistrypriv->ldpc_cap = 0x00;
6360
} else if (arg == 1) {
6361
RTW_INFO("driver set LDPC cap = 0x%x\n", extra_arg);
6362
pregistrypriv->ldpc_cap = (u8)(extra_arg & 0x33);
6363
}
6364
}
6365
break;
6366
case 0x1a: {
6367
struct registry_priv *pregistrypriv = &padapter->registrypriv;
6368
/* extra_arg : */
6369
/* BIT0: Enable VHT STBC Rx, BIT1: Enable VHT STBC Tx, */
6370
/* BIT4: Enable HT STBC Rx, BIT5: Enable HT STBC Tx */
6371
if (arg == 0) {
6372
RTW_INFO("driver disable STBC\n");
6373
pregistrypriv->stbc_cap = 0x00;
6374
} else if (arg == 1) {
6375
RTW_INFO("driver set STBC cap = 0x%x\n", extra_arg);
6376
pregistrypriv->stbc_cap = (u8)(extra_arg & 0x33);
6377
}
6378
}
6379
break;
6380
#endif /* CONFIG_80211N_HT */
6381
case 0x1b: {
6382
struct registry_priv *pregistrypriv = &padapter->registrypriv;
6383
6384
if (arg == 0) {
6385
RTW_INFO("disable driver ctrl max_rx_rate, reset to default_rate_set\n");
6386
init_mlme_default_rate_set(padapter);
6387
#ifdef CONFIG_80211N_HT
6388
pregistrypriv->ht_enable = (u8)rtw_ht_enable;
6389
#endif /* CONFIG_80211N_HT */
6390
} else if (arg == 1) {
6391
6392
int i;
6393
u8 max_rx_rate;
6394
6395
RTW_INFO("enable driver ctrl max_rx_rate = 0x%x\n", extra_arg);
6396
6397
max_rx_rate = (u8)extra_arg;
6398
6399
if (max_rx_rate < 0xc) { /* max_rx_rate < MSC0->B or G -> disable HT */
6400
#ifdef CONFIG_80211N_HT
6401
pregistrypriv->ht_enable = 0;
6402
#endif /* CONFIG_80211N_HT */
6403
for (i = 0; i < NumRates; i++) {
6404
if (pmlmeext->datarate[i] > max_rx_rate)
6405
pmlmeext->datarate[i] = 0xff;
6406
}
6407
6408
}
6409
#ifdef CONFIG_80211N_HT
6410
else if (max_rx_rate < 0x1c) { /* mcs0~mcs15 */
6411
u32 mcs_bitmap = 0x0;
6412
6413
for (i = 0; i < ((max_rx_rate + 1) - 0xc); i++)
6414
mcs_bitmap |= BIT(i);
6415
6416
set_mcs_rate_by_mask(pmlmeext->default_supported_mcs_set, mcs_bitmap);
6417
}
6418
#endif /* CONFIG_80211N_HT */
6419
}
6420
}
6421
break;
6422
case 0x1c: { /* enable/disable driver control AMPDU Density for peer sta's rx */
6423
if (arg == 0) {
6424
RTW_INFO("disable driver ctrl ampdu density\n");
6425
padapter->driver_ampdu_spacing = 0xFF;
6426
} else if (arg == 1) {
6427
6428
RTW_INFO("enable driver ctrl ampdu density = %d\n", extra_arg);
6429
6430
if (extra_arg > 0x07)
6431
padapter->driver_ampdu_spacing = 0xFF;
6432
else
6433
padapter->driver_ampdu_spacing = extra_arg;
6434
}
6435
}
6436
break;
6437
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
6438
case 0x1e: {
6439
RTW_INFO("===========================================\n");
6440
rtw_noise_measure_curchan(padapter);
6441
RTW_INFO("===========================================\n");
6442
}
6443
break;
6444
#endif
6445
6446
6447
#if defined(CONFIG_SDIO_HCI) && defined(CONFIG_SDIO_INDIRECT_ACCESS) && defined(DBG_SDIO_INDIRECT_ACCESS)
6448
case 0x1f:
6449
{
6450
int i, j = 0, test_cnts = 0;
6451
static u8 test_code = 0x5A;
6452
static u32 data_misatch_cnt = 0, d_acc_err_cnt = 0;
6453
6454
u32 d_data, i_data;
6455
u32 imr;
6456
6457
test_cnts = extra_arg;
6458
for (i = 0; i < test_cnts; i++) {
6459
if (RTW_CANNOT_IO(padapter))
6460
break;
6461
6462
rtw_write8(padapter, 0x07, test_code);
6463
6464
d_data = rtw_read32(padapter, 0x04);
6465
imr = rtw_read32(padapter, 0x10250014);
6466
rtw_write32(padapter, 0x10250014, 0);
6467
rtw_msleep_os(50);
6468
6469
i_data = rtw_sd_iread32(padapter, 0x04);
6470
6471
rtw_write32(padapter, 0x10250014, imr);
6472
6473
if (d_data != i_data) {
6474
data_misatch_cnt++;
6475
RTW_ERR("d_data :0x%08x, i_data : 0x%08x\n", d_data, i_data);
6476
}
6477
6478
if (test_code != (i_data >> 24)) {
6479
d_acc_err_cnt++;
6480
rtw_write8(padapter, 0x07, 0xAA);
6481
RTW_ERR("test_code :0x%02x, i_data : 0x%08x\n", test_code, i_data);
6482
}
6483
if ((j++) == 100) {
6484
rtw_msleep_os(2000);
6485
RTW_INFO(" Indirect access testing..........%d/%d\n", i, test_cnts);
6486
j = 0;
6487
}
6488
6489
test_code = ~test_code;
6490
rtw_msleep_os(50);
6491
}
6492
RTW_INFO("========Indirect access test=========\n");
6493
RTW_INFO(" test_cnts = %d\n", test_cnts);
6494
RTW_INFO(" direct & indirect read32 data missatch cnts = %d\n", data_misatch_cnt);
6495
RTW_INFO(" indirect rdata is not equal to wdata cnts = %d\n", d_acc_err_cnt);
6496
RTW_INFO("========Indirect access test=========\n\n");
6497
data_misatch_cnt = d_acc_err_cnt = 0;
6498
6499
}
6500
break;
6501
#endif
6502
case 0x20:
6503
{
6504
if (arg == 0xAA) {
6505
u8 page_offset, page_num;
6506
6507
page_offset = (u8)(extra_arg >> 16);
6508
page_num = (u8)(extra_arg & 0xFF);
6509
rtw_dump_rsvd_page(RTW_DBGDUMP, padapter, page_offset, page_num);
6510
}
6511
#ifdef CONFIG_SUPPORT_FIFO_DUMP
6512
else {
6513
u8 fifo_sel;
6514
u32 addr, size;
6515
6516
fifo_sel = (u8)(arg & 0x0F);
6517
addr = (extra_arg >> 16) & 0xFFFF;
6518
size = extra_arg & 0xFFFF;
6519
rtw_dump_fifo(RTW_DBGDUMP, padapter, fifo_sel, addr, size);
6520
}
6521
#endif
6522
}
6523
break;
6524
6525
case 0x23: {
6526
RTW_INFO("turn %s the bNotifyChannelChange Variable\n", (extra_arg == 1) ? "on" : "off");
6527
padapter->bNotifyChannelChange = extra_arg;
6528
break;
6529
}
6530
case 0x24: {
6531
#ifdef CONFIG_P2P
6532
RTW_INFO("turn %s the bShowGetP2PState Variable\n", (extra_arg == 1) ? "on" : "off");
6533
padapter->bShowGetP2PState = extra_arg;
6534
#endif /* CONFIG_P2P */
6535
break;
6536
}
6537
#ifdef CONFIG_GPIO_API
6538
case 0x25: { /* Get GPIO register */
6539
/*
6540
* dbg 0x7f250000 [gpio_num], Get gpio value, gpio_num:0~7
6541
*/
6542
6543
u8 value;
6544
RTW_INFO("Read GPIO Value extra_arg = %d\n", extra_arg);
6545
value = rtw_hal_get_gpio(padapter, extra_arg);
6546
RTW_INFO("Read GPIO Value = %d\n", value);
6547
break;
6548
}
6549
case 0x26: { /* Set GPIO direction */
6550
6551
/* dbg 0x7f26000x [y], Set gpio direction,
6552
* x: gpio_num,4~7 y: indicate direction, 0~1
6553
*/
6554
6555
int value;
6556
RTW_INFO("Set GPIO Direction! arg = %d ,extra_arg=%d\n", arg , extra_arg);
6557
value = rtw_hal_config_gpio(padapter, arg, extra_arg);
6558
RTW_INFO("Set GPIO Direction %s\n", (value == -1) ? "Fail!!!" : "Success");
6559
break;
6560
}
6561
case 0x27: { /* Set GPIO output direction value */
6562
/*
6563
* dbg 0x7f27000x [y], Set gpio output direction value,
6564
* x: gpio_num,4~7 y: indicate direction, 0~1
6565
*/
6566
6567
int value;
6568
RTW_INFO("Set GPIO Value! arg = %d ,extra_arg=%d\n", arg , extra_arg);
6569
value = rtw_hal_set_gpio_output_value(padapter, arg, extra_arg);
6570
RTW_INFO("Set GPIO Value %s\n", (value == -1) ? "Fail!!!" : "Success");
6571
break;
6572
}
6573
#endif
6574
#ifdef DBG_CMD_QUEUE
6575
case 0x28: {
6576
dump_cmd_id = extra_arg;
6577
RTW_INFO("dump_cmd_id:%d\n", dump_cmd_id);
6578
}
6579
break;
6580
#endif /* DBG_CMD_QUEUE */
6581
case 0xaa: {
6582
if ((extra_arg & 0x7F) > 0x3F)
6583
extra_arg = 0xFF;
6584
RTW_INFO("chang data rate to :0x%02x\n", extra_arg);
6585
padapter->fix_rate = extra_arg;
6586
}
6587
break;
6588
case 0xdd: { /* registers dump , 0 for mac reg,1 for bb reg, 2 for rf reg */
6589
if (extra_arg == 0)
6590
mac_reg_dump(RTW_DBGDUMP, padapter);
6591
else if (extra_arg == 1)
6592
bb_reg_dump(RTW_DBGDUMP, padapter);
6593
else if (extra_arg == 2)
6594
rf_reg_dump(RTW_DBGDUMP, padapter);
6595
else if (extra_arg == 11)
6596
bb_reg_dump_ex(RTW_DBGDUMP, padapter);
6597
}
6598
break;
6599
6600
case 0xee: {
6601
RTW_INFO(" === please control /proc to trun on/off PHYDM func ===\n");
6602
}
6603
break;
6604
6605
case 0xfd:
6606
rtw_write8(padapter, 0xc50, arg);
6607
RTW_INFO("wr(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6608
rtw_write8(padapter, 0xc58, arg);
6609
RTW_INFO("wr(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6610
break;
6611
case 0xfe:
6612
RTW_INFO("rd(0xc50)=0x%x\n", rtw_read8(padapter, 0xc50));
6613
RTW_INFO("rd(0xc58)=0x%x\n", rtw_read8(padapter, 0xc58));
6614
break;
6615
case 0xff: {
6616
RTW_INFO("dbg(0x210)=0x%x\n", rtw_read32(padapter, 0x210));
6617
RTW_INFO("dbg(0x608)=0x%x\n", rtw_read32(padapter, 0x608));
6618
RTW_INFO("dbg(0x280)=0x%x\n", rtw_read32(padapter, 0x280));
6619
RTW_INFO("dbg(0x284)=0x%x\n", rtw_read32(padapter, 0x284));
6620
RTW_INFO("dbg(0x288)=0x%x\n", rtw_read32(padapter, 0x288));
6621
6622
RTW_INFO("dbg(0x664)=0x%x\n", rtw_read32(padapter, 0x664));
6623
6624
6625
RTW_INFO("\n");
6626
6627
RTW_INFO("dbg(0x430)=0x%x\n", rtw_read32(padapter, 0x430));
6628
RTW_INFO("dbg(0x438)=0x%x\n", rtw_read32(padapter, 0x438));
6629
6630
RTW_INFO("dbg(0x440)=0x%x\n", rtw_read32(padapter, 0x440));
6631
6632
RTW_INFO("dbg(0x458)=0x%x\n", rtw_read32(padapter, 0x458));
6633
6634
RTW_INFO("dbg(0x484)=0x%x\n", rtw_read32(padapter, 0x484));
6635
RTW_INFO("dbg(0x488)=0x%x\n", rtw_read32(padapter, 0x488));
6636
6637
RTW_INFO("dbg(0x444)=0x%x\n", rtw_read32(padapter, 0x444));
6638
RTW_INFO("dbg(0x448)=0x%x\n", rtw_read32(padapter, 0x448));
6639
RTW_INFO("dbg(0x44c)=0x%x\n", rtw_read32(padapter, 0x44c));
6640
RTW_INFO("dbg(0x450)=0x%x\n", rtw_read32(padapter, 0x450));
6641
}
6642
break;
6643
}
6644
break;
6645
default:
6646
RTW_INFO("error dbg cmd!\n");
6647
break;
6648
}
6649
6650
6651
return ret;
6652
6653
}
6654
6655
static int wpa_set_param(struct net_device *dev, u8 name, u32 value)
6656
{
6657
uint ret = 0;
6658
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6659
6660
switch (name) {
6661
case IEEE_PARAM_WPA_ENABLED:
6662
6663
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X; /* 802.1x */
6664
6665
/* ret = ieee80211_wpa_enable(ieee, value); */
6666
6667
switch ((value) & 0xff) {
6668
case 1: /* WPA */
6669
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK; /* WPA_PSK */
6670
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
6671
break;
6672
case 2: /* WPA2 */
6673
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK; /* WPA2_PSK */
6674
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
6675
break;
6676
}
6677
6678
6679
break;
6680
6681
case IEEE_PARAM_TKIP_COUNTERMEASURES:
6682
/* ieee->tkip_countermeasures=value; */
6683
break;
6684
6685
case IEEE_PARAM_DROP_UNENCRYPTED: {
6686
/* HACK:
6687
*
6688
* wpa_supplicant calls set_wpa_enabled when the driver
6689
* is loaded and unloaded, regardless of if WPA is being
6690
* used. No other calls are made which can be used to
6691
* determine if encryption will be used or not prior to
6692
* association being expected. If encryption is not being
6693
* used, drop_unencrypted is set to false, else true -- we
6694
* can use this to determine if the CAP_PRIVACY_ON bit should
6695
* be set.
6696
*/
6697
6698
#if 0
6699
struct ieee80211_security sec = {
6700
.flags = SEC_ENABLED,
6701
.enabled = value,
6702
};
6703
ieee->drop_unencrypted = value;
6704
/* We only change SEC_LEVEL for open mode. Others
6705
* are set by ipw_wpa_set_encryption.
6706
*/
6707
if (!value) {
6708
sec.flags |= SEC_LEVEL;
6709
sec.level = SEC_LEVEL_0;
6710
} else {
6711
sec.flags |= SEC_LEVEL;
6712
sec.level = SEC_LEVEL_1;
6713
}
6714
if (ieee->set_security)
6715
ieee->set_security(ieee->dev, &sec);
6716
#endif
6717
break;
6718
6719
}
6720
case IEEE_PARAM_PRIVACY_INVOKED:
6721
6722
/* ieee->privacy_invoked=value; */
6723
6724
break;
6725
6726
case IEEE_PARAM_AUTH_ALGS:
6727
6728
ret = wpa_set_auth_algs(dev, value);
6729
6730
break;
6731
6732
case IEEE_PARAM_IEEE_802_1X:
6733
6734
/* ieee->ieee802_1x=value; */
6735
6736
break;
6737
6738
case IEEE_PARAM_WPAX_SELECT:
6739
6740
/* added for WPA2 mixed mode */
6741
/*RTW_WARN("------------------------>wpax value = %x\n", value);*/
6742
/*
6743
spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags);
6744
ieee->wpax_type_set = 1;
6745
ieee->wpax_type_notify = value;
6746
spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags);
6747
*/
6748
6749
break;
6750
6751
default:
6752
6753
6754
6755
ret = -EOPNOTSUPP;
6756
6757
6758
break;
6759
6760
}
6761
6762
return ret;
6763
6764
}
6765
6766
static int wpa_mlme(struct net_device *dev, u32 command, u32 reason)
6767
{
6768
int ret = 0;
6769
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6770
6771
switch (command) {
6772
case IEEE_MLME_STA_DEAUTH:
6773
6774
if (!rtw_set_802_11_disassociate(padapter))
6775
ret = -1;
6776
6777
break;
6778
6779
case IEEE_MLME_STA_DISASSOC:
6780
6781
if (!rtw_set_802_11_disassociate(padapter))
6782
ret = -1;
6783
6784
break;
6785
6786
default:
6787
ret = -EOPNOTSUPP;
6788
break;
6789
}
6790
#ifdef CONFIG_RTW_REPEATER_SON
6791
rtw_rson_do_disconnect(padapter);
6792
#endif
6793
return ret;
6794
6795
}
6796
6797
static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p)
6798
{
6799
struct ieee_param *param;
6800
uint ret = 0;
6801
6802
/* down(&ieee->wx_sem); */
6803
6804
if (p->length < sizeof(struct ieee_param) || !p->pointer) {
6805
ret = -EINVAL;
6806
goto out;
6807
}
6808
6809
param = (struct ieee_param *)rtw_malloc(p->length);
6810
if (param == NULL) {
6811
ret = -ENOMEM;
6812
goto out;
6813
}
6814
6815
if (copy_from_user(param, p->pointer, p->length)) {
6816
rtw_mfree((u8 *)param, p->length);
6817
ret = -EFAULT;
6818
goto out;
6819
}
6820
6821
switch (param->cmd) {
6822
6823
case IEEE_CMD_SET_WPA_PARAM:
6824
ret = wpa_set_param(dev, param->u.wpa_param.name, param->u.wpa_param.value);
6825
break;
6826
6827
case IEEE_CMD_SET_WPA_IE:
6828
/* ret = wpa_set_wpa_ie(dev, param, p->length); */
6829
ret = rtw_set_wpa_ie((_adapter *)rtw_netdev_priv(dev), (char *)param->u.wpa_ie.data, (u16)param->u.wpa_ie.len);
6830
break;
6831
6832
case IEEE_CMD_SET_ENCRYPTION:
6833
ret = wpa_set_encryption(dev, param, p->length);
6834
break;
6835
6836
case IEEE_CMD_MLME:
6837
ret = wpa_mlme(dev, param->u.mlme.command, param->u.mlme.reason_code);
6838
break;
6839
6840
default:
6841
RTW_INFO("Unknown WPA supplicant request: %d\n", param->cmd);
6842
ret = -EOPNOTSUPP;
6843
break;
6844
6845
}
6846
6847
if (ret == 0 && copy_to_user(p->pointer, param, p->length))
6848
ret = -EFAULT;
6849
6850
rtw_mfree((u8 *)param, p->length);
6851
6852
out:
6853
6854
/* up(&ieee->wx_sem); */
6855
6856
return ret;
6857
6858
}
6859
6860
#ifdef CONFIG_AP_MODE
6861
static int rtw_set_encryption(struct net_device *dev, struct ieee_param *param, u32 param_len)
6862
{
6863
int ret = 0;
6864
u32 wep_key_idx, wep_key_len, wep_total_len;
6865
NDIS_802_11_WEP *pwep = NULL;
6866
struct sta_info *psta = NULL, *pbcmc_sta = NULL;
6867
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
6868
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6869
struct security_priv *psecuritypriv = &(padapter->securitypriv);
6870
struct sta_priv *pstapriv = &padapter->stapriv;
6871
6872
RTW_INFO("%s\n", __FUNCTION__);
6873
6874
param->u.crypt.err = 0;
6875
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
6876
6877
/* sizeof(struct ieee_param) = 64 bytes; */
6878
/* if (param_len != (u32) ((u8 *) param->u.crypt.key - (u8 *) param) + param->u.crypt.key_len) */
6879
if (param_len != sizeof(struct ieee_param) + param->u.crypt.key_len) {
6880
ret = -EINVAL;
6881
goto exit;
6882
}
6883
6884
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
6885
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
6886
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
6887
if (param->u.crypt.idx >= WEP_KEYS
6888
#ifdef CONFIG_IEEE80211W
6889
&& param->u.crypt.idx > BIP_MAX_KEYID
6890
#endif /* CONFIG_IEEE80211W */
6891
) {
6892
ret = -EINVAL;
6893
goto exit;
6894
}
6895
} else {
6896
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
6897
if (!psta) {
6898
/* ret = -EINVAL; */
6899
RTW_INFO("rtw_set_encryption(), sta has already been removed or never been added\n");
6900
goto exit;
6901
}
6902
}
6903
6904
if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
6905
/* todo:clear default encryption keys */
6906
6907
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
6908
psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
6909
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
6910
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
6911
6912
RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
6913
6914
goto exit;
6915
}
6916
6917
6918
if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
6919
RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
6920
6921
wep_key_idx = param->u.crypt.idx;
6922
wep_key_len = param->u.crypt.key_len;
6923
6924
RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
6925
6926
if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
6927
ret = -EINVAL;
6928
goto exit;
6929
}
6930
6931
6932
if (wep_key_len > 0) {
6933
wep_key_len = wep_key_len <= 5 ? 5 : 13;
6934
wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
6935
pwep = (NDIS_802_11_WEP *)rtw_malloc(wep_total_len);
6936
if (pwep == NULL) {
6937
RTW_INFO(" r871x_set_encryption: pwep allocate fail !!!\n");
6938
goto exit;
6939
}
6940
6941
_rtw_memset(pwep, 0, wep_total_len);
6942
6943
pwep->KeyLength = wep_key_len;
6944
pwep->Length = wep_total_len;
6945
6946
}
6947
6948
pwep->KeyIndex = wep_key_idx;
6949
6950
_rtw_memcpy(pwep->KeyMaterial, param->u.crypt.key, pwep->KeyLength);
6951
6952
if (param->u.crypt.set_tx) {
6953
RTW_INFO("wep, set_tx=1\n");
6954
6955
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
6956
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
6957
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
6958
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6959
6960
if (pwep->KeyLength == 13) {
6961
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
6962
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
6963
}
6964
6965
6966
psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
6967
6968
_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6969
6970
psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6971
6972
rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 1);
6973
} else {
6974
RTW_INFO("wep, set_tx=0\n");
6975
6976
/* don't update "psecuritypriv->dot11PrivacyAlgrthm" and */
6977
/* "psecuritypriv->dot11PrivacyKeyIndex=keyid", but can rtw_set_key to cam */
6978
6979
_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), pwep->KeyMaterial, pwep->KeyLength);
6980
6981
psecuritypriv->dot11DefKeylen[wep_key_idx] = pwep->KeyLength;
6982
6983
rtw_ap_set_wep_key(padapter, pwep->KeyMaterial, pwep->KeyLength, wep_key_idx, 0);
6984
}
6985
6986
goto exit;
6987
6988
}
6989
6990
6991
if (!psta && check_fwstate(pmlmepriv, WIFI_AP_STATE)) /* */ { /* group key */
6992
if (param->u.crypt.set_tx == 1) {
6993
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
6994
RTW_INFO(FUNC_ADPT_FMT" set WEP TX GTK idx:%u, len:%u\n"
6995
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
6996
_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
6997
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
6998
if (param->u.crypt.key_len == 13)
6999
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
7000
7001
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7002
RTW_INFO(FUNC_ADPT_FMT" set TKIP TX GTK idx:%u, len:%u\n"
7003
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
7004
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
7005
_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
7006
/* set mic key */
7007
_rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
7008
_rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
7009
psecuritypriv->busetkipkey = _TRUE;
7010
7011
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7012
RTW_INFO(FUNC_ADPT_FMT" set CCMP TX GTK idx:%u, len:%u\n"
7013
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
7014
psecuritypriv->dot118021XGrpPrivacy = _AES_;
7015
_rtw_memcpy(psecuritypriv->dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
7016
7017
#ifdef CONFIG_IEEE80211W
7018
} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
7019
RTW_INFO(FUNC_ADPT_FMT" set TX IGTK idx:%u, len:%u\n"
7020
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
7021
_rtw_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));
7022
psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
7023
psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
7024
psecuritypriv->binstallBIPkey = _TRUE;
7025
goto exit;
7026
#endif /* CONFIG_IEEE80211W */
7027
7028
} else if (strcmp(param->u.crypt.alg, "none") == 0) {
7029
RTW_INFO(FUNC_ADPT_FMT" clear group key, idx:%u\n"
7030
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx);
7031
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
7032
} else {
7033
RTW_WARN(FUNC_ADPT_FMT" set group key, not support\n"
7034
, FUNC_ADPT_ARG(padapter));
7035
goto exit;
7036
}
7037
7038
psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
7039
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
7040
if (pbcmc_sta) {
7041
pbcmc_sta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
7042
pbcmc_sta->ieee8021x_blocked = _FALSE;
7043
pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy */
7044
}
7045
psecuritypriv->binstallGrpkey = _TRUE;
7046
psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
7047
7048
rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
7049
}
7050
7051
goto exit;
7052
7053
}
7054
7055
if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
7056
if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
7057
if (param->u.crypt.set_tx == 1) {
7058
_rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
7059
7060
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
7061
RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n"
7062
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7063
, param->u.crypt.idx, param->u.crypt.key_len);
7064
psta->dot118021XPrivacy = _WEP40_;
7065
if (param->u.crypt.key_len == 13)
7066
psta->dot118021XPrivacy = _WEP104_;
7067
7068
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
7069
RTW_INFO(FUNC_ADPT_FMT" set TKIP PTK of "MAC_FMT" idx:%u, len:%u\n"
7070
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7071
, param->u.crypt.idx, param->u.crypt.key_len);
7072
psta->dot118021XPrivacy = _TKIP_;
7073
/* set mic key */
7074
_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
7075
_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
7076
psecuritypriv->busetkipkey = _TRUE;
7077
7078
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
7079
RTW_INFO(FUNC_ADPT_FMT" set CCMP PTK of "MAC_FMT" idx:%u, len:%u\n"
7080
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7081
, param->u.crypt.idx, param->u.crypt.key_len);
7082
psta->dot118021XPrivacy = _AES_;
7083
7084
} else if (strcmp(param->u.crypt.alg, "none") == 0) {
7085
RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n"
7086
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
7087
, param->u.crypt.idx);
7088
psta->dot118021XPrivacy = _NO_PRIVACY_;
7089
7090
} else {
7091
RTW_WARN(FUNC_ADPT_FMT" set pairwise key of "MAC_FMT", not support\n"
7092
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
7093
goto exit;
7094
}
7095
7096
psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
7097
psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
7098
psta->ieee8021x_blocked = _FALSE;
7099
7100
if (psta->dot118021XPrivacy != _NO_PRIVACY_) {
7101
psta->bpairwise_key_installed = _TRUE;
7102
7103
/* WPA2 key-handshake has completed */
7104
if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
7105
psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
7106
}
7107
7108
rtw_ap_set_pairwise_key(padapter, psta);
7109
} else {
7110
RTW_WARN(FUNC_ADPT_FMT" set group key of "MAC_FMT", not support\n"
7111
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
7112
goto exit;
7113
}
7114
7115
}
7116
7117
}
7118
7119
exit:
7120
7121
if (pwep)
7122
rtw_mfree((u8 *)pwep, wep_total_len);
7123
7124
return ret;
7125
7126
}
7127
7128
static int rtw_set_beacon(struct net_device *dev, struct ieee_param *param, int len)
7129
{
7130
int ret = 0;
7131
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7132
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7133
struct sta_priv *pstapriv = &padapter->stapriv;
7134
unsigned char *pbuf = param->u.bcn_ie.buf;
7135
7136
7137
RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7138
7139
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7140
return -EINVAL;
7141
7142
_rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2);
7143
7144
if ((pstapriv->max_num_sta > NUM_STA) || (pstapriv->max_num_sta <= 0))
7145
pstapriv->max_num_sta = NUM_STA;
7146
7147
7148
if (rtw_check_beacon_data(padapter, pbuf, (len - 12 - 2)) == _SUCCESS) /* 12 = param header, 2:no packed */
7149
ret = 0;
7150
else
7151
ret = -EINVAL;
7152
7153
7154
return ret;
7155
7156
}
7157
7158
static int rtw_hostapd_sta_flush(struct net_device *dev)
7159
{
7160
/* _irqL irqL; */
7161
/* _list *phead, *plist; */
7162
int ret = 0;
7163
/* struct sta_info *psta = NULL; */
7164
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7165
/* struct sta_priv *pstapriv = &padapter->stapriv; */
7166
7167
RTW_INFO("%s\n", __FUNCTION__);
7168
7169
flush_all_cam_entry(padapter); /* clear CAM */
7170
#ifdef CONFIG_AP_MODE
7171
ret = rtw_sta_flush(padapter, _TRUE);
7172
#endif
7173
return ret;
7174
7175
}
7176
7177
static int rtw_add_sta(struct net_device *dev, struct ieee_param *param)
7178
{
7179
int ret = 0;
7180
struct sta_info *psta = NULL;
7181
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7182
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7183
struct sta_priv *pstapriv = &padapter->stapriv;
7184
7185
RTW_INFO("rtw_add_sta(aid=%d)=" MAC_FMT "\n", param->u.add_sta.aid, MAC_ARG(param->sta_addr));
7186
7187
if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7188
return -EINVAL;
7189
7190
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7191
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7192
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7193
return -EINVAL;
7194
7195
#if 0
7196
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7197
if (psta) {
7198
RTW_INFO("rtw_add_sta(), free has been added psta=%p\n", psta);
7199
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7200
rtw_free_stainfo(padapter, psta);
7201
/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
7202
7203
psta = NULL;
7204
}
7205
#endif
7206
/* psta = rtw_alloc_stainfo(pstapriv, param->sta_addr); */
7207
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7208
if (psta) {
7209
int flags = param->u.add_sta.flags;
7210
7211
/* RTW_INFO("rtw_add_sta(), init sta's variables, psta=%p\n", psta); */
7212
7213
psta->cmn.aid = param->u.add_sta.aid;/* aid=1~2007 */
7214
7215
_rtw_memcpy(psta->bssrateset, param->u.add_sta.tx_supp_rates, 16);
7216
7217
7218
/* check wmm cap. */
7219
if (WLAN_STA_WME & flags)
7220
psta->qos_option = 1;
7221
else
7222
psta->qos_option = 0;
7223
7224
if (pmlmepriv->qospriv.qos_option == 0)
7225
psta->qos_option = 0;
7226
7227
7228
#ifdef CONFIG_80211N_HT
7229
/* chec 802.11n ht cap. */
7230
if (padapter->registrypriv.ht_enable &&
7231
is_supported_ht(padapter->registrypriv.wireless_mode) &&
7232
(WLAN_STA_HT & flags)) {
7233
psta->htpriv.ht_option = _TRUE;
7234
psta->qos_option = 1;
7235
_rtw_memcpy((void *)&psta->htpriv.ht_cap, (void *)&param->u.add_sta.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7236
} else
7237
psta->htpriv.ht_option = _FALSE;
7238
7239
if (pmlmepriv->htpriv.ht_option == _FALSE)
7240
psta->htpriv.ht_option = _FALSE;
7241
7242
#endif
7243
7244
7245
update_sta_info_apmode(padapter, psta);
7246
7247
7248
} else
7249
ret = -ENOMEM;
7250
7251
return ret;
7252
7253
}
7254
7255
static int rtw_del_sta(struct net_device *dev, struct ieee_param *param)
7256
{
7257
_irqL irqL;
7258
int ret = 0;
7259
struct sta_info *psta = NULL;
7260
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7261
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7262
struct sta_priv *pstapriv = &padapter->stapriv;
7263
7264
RTW_INFO("rtw_del_sta=" MAC_FMT "\n", MAC_ARG(param->sta_addr));
7265
7266
if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7267
return -EINVAL;
7268
7269
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7270
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7271
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7272
return -EINVAL;
7273
7274
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7275
if (psta) {
7276
u8 updated = _FALSE;
7277
7278
/* RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid); */
7279
7280
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7281
if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
7282
rtw_list_delete(&psta->asoc_list);
7283
pstapriv->asoc_list_cnt--;
7284
updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
7285
7286
}
7287
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
7288
7289
associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
7290
7291
psta = NULL;
7292
7293
} else {
7294
RTW_INFO("rtw_del_sta(), sta has already been removed or never been added\n");
7295
7296
/* ret = -1; */
7297
}
7298
7299
7300
return ret;
7301
7302
}
7303
7304
static int rtw_ioctl_get_sta_data(struct net_device *dev, struct ieee_param *param, int len)
7305
{
7306
int ret = 0;
7307
struct sta_info *psta = NULL;
7308
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7309
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7310
struct sta_priv *pstapriv = &padapter->stapriv;
7311
struct ieee_param_ex *param_ex = (struct ieee_param_ex *)param;
7312
struct sta_data *psta_data = (struct sta_data *)param_ex->data;
7313
7314
RTW_INFO("rtw_ioctl_get_sta_info, sta_addr: " MAC_FMT "\n", MAC_ARG(param_ex->sta_addr));
7315
7316
if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7317
return -EINVAL;
7318
7319
if (param_ex->sta_addr[0] == 0xff && param_ex->sta_addr[1] == 0xff &&
7320
param_ex->sta_addr[2] == 0xff && param_ex->sta_addr[3] == 0xff &&
7321
param_ex->sta_addr[4] == 0xff && param_ex->sta_addr[5] == 0xff)
7322
return -EINVAL;
7323
7324
psta = rtw_get_stainfo(pstapriv, param_ex->sta_addr);
7325
if (psta) {
7326
#if 0
7327
struct {
7328
u16 aid;
7329
u16 capability;
7330
int flags;
7331
u32 sta_set;
7332
u8 tx_supp_rates[16];
7333
u32 tx_supp_rates_len;
7334
struct rtw_ieee80211_ht_cap ht_cap;
7335
u64 rx_pkts;
7336
u64 rx_bytes;
7337
u64 rx_drops;
7338
u64 tx_pkts;
7339
u64 tx_bytes;
7340
u64 tx_drops;
7341
} get_sta;
7342
#endif
7343
psta_data->aid = (u16)psta->cmn.aid;
7344
psta_data->capability = psta->capability;
7345
psta_data->flags = psta->flags;
7346
7347
/*
7348
nonerp_set : BIT(0)
7349
no_short_slot_time_set : BIT(1)
7350
no_short_preamble_set : BIT(2)
7351
no_ht_gf_set : BIT(3)
7352
no_ht_set : BIT(4)
7353
ht_20mhz_set : BIT(5)
7354
*/
7355
7356
psta_data->sta_set = ((psta->nonerp_set) |
7357
(psta->no_short_slot_time_set << 1) |
7358
(psta->no_short_preamble_set << 2) |
7359
(psta->no_ht_gf_set << 3) |
7360
(psta->no_ht_set << 4) |
7361
(psta->ht_20mhz_set << 5));
7362
7363
psta_data->tx_supp_rates_len = psta->bssratelen;
7364
_rtw_memcpy(psta_data->tx_supp_rates, psta->bssrateset, psta->bssratelen);
7365
#ifdef CONFIG_80211N_HT
7366
if(padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))
7367
_rtw_memcpy(&psta_data->ht_cap, &psta->htpriv.ht_cap, sizeof(struct rtw_ieee80211_ht_cap));
7368
#endif /* CONFIG_80211N_HT */
7369
psta_data->rx_pkts = psta->sta_stats.rx_data_pkts;
7370
psta_data->rx_bytes = psta->sta_stats.rx_bytes;
7371
psta_data->rx_drops = psta->sta_stats.rx_drops;
7372
7373
psta_data->tx_pkts = psta->sta_stats.tx_pkts;
7374
psta_data->tx_bytes = psta->sta_stats.tx_bytes;
7375
psta_data->tx_drops = psta->sta_stats.tx_drops;
7376
7377
7378
} else
7379
ret = -1;
7380
7381
return ret;
7382
7383
}
7384
7385
static int rtw_get_sta_wpaie(struct net_device *dev, struct ieee_param *param)
7386
{
7387
int ret = 0;
7388
struct sta_info *psta = NULL;
7389
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7390
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7391
struct sta_priv *pstapriv = &padapter->stapriv;
7392
7393
RTW_INFO("rtw_get_sta_wpaie, sta_addr: " MAC_FMT "\n", MAC_ARG(param->sta_addr));
7394
7395
if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE)) != _TRUE)
7396
return -EINVAL;
7397
7398
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7399
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7400
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7401
return -EINVAL;
7402
7403
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
7404
if (psta) {
7405
if ((psta->wpa_ie[0] == WLAN_EID_RSN) || (psta->wpa_ie[0] == WLAN_EID_GENERIC)) {
7406
int wpa_ie_len;
7407
int copy_len;
7408
7409
wpa_ie_len = psta->wpa_ie[1];
7410
7411
copy_len = ((wpa_ie_len + 2) > sizeof(psta->wpa_ie)) ? (sizeof(psta->wpa_ie)) : (wpa_ie_len + 2);
7412
7413
param->u.wpa_ie.len = copy_len;
7414
7415
_rtw_memcpy(param->u.wpa_ie.reserved, psta->wpa_ie, copy_len);
7416
} else {
7417
/* ret = -1; */
7418
RTW_INFO("sta's wpa_ie is NONE\n");
7419
}
7420
} else
7421
ret = -1;
7422
7423
return ret;
7424
7425
}
7426
7427
static int rtw_set_wps_beacon(struct net_device *dev, struct ieee_param *param, int len)
7428
{
7429
int ret = 0;
7430
unsigned char wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
7431
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7432
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7433
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7434
int ie_len;
7435
7436
RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7437
7438
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7439
return -EINVAL;
7440
7441
ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7442
7443
7444
if (pmlmepriv->wps_beacon_ie) {
7445
rtw_mfree(pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7446
pmlmepriv->wps_beacon_ie = NULL;
7447
}
7448
7449
if (ie_len > 0) {
7450
pmlmepriv->wps_beacon_ie = rtw_malloc(ie_len);
7451
pmlmepriv->wps_beacon_ie_len = ie_len;
7452
if (pmlmepriv->wps_beacon_ie == NULL) {
7453
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7454
return -EINVAL;
7455
}
7456
7457
_rtw_memcpy(pmlmepriv->wps_beacon_ie, param->u.bcn_ie.buf, ie_len);
7458
7459
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, 0);
7460
7461
pmlmeext->bstart_bss = _TRUE;
7462
7463
}
7464
7465
7466
return ret;
7467
7468
}
7469
7470
static int rtw_set_wps_probe_resp(struct net_device *dev, struct ieee_param *param, int len)
7471
{
7472
int ret = 0;
7473
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7474
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7475
int ie_len;
7476
7477
RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7478
7479
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7480
return -EINVAL;
7481
7482
ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7483
7484
7485
if (pmlmepriv->wps_probe_resp_ie) {
7486
rtw_mfree(pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
7487
pmlmepriv->wps_probe_resp_ie = NULL;
7488
}
7489
7490
if (ie_len > 0) {
7491
pmlmepriv->wps_probe_resp_ie = rtw_malloc(ie_len);
7492
pmlmepriv->wps_probe_resp_ie_len = ie_len;
7493
if (pmlmepriv->wps_probe_resp_ie == NULL) {
7494
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7495
return -EINVAL;
7496
}
7497
_rtw_memcpy(pmlmepriv->wps_probe_resp_ie, param->u.bcn_ie.buf, ie_len);
7498
}
7499
7500
7501
return ret;
7502
7503
}
7504
7505
static int rtw_set_wps_assoc_resp(struct net_device *dev, struct ieee_param *param, int len)
7506
{
7507
int ret = 0;
7508
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7509
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7510
int ie_len;
7511
7512
RTW_INFO("%s, len=%d\n", __FUNCTION__, len);
7513
7514
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7515
return -EINVAL;
7516
7517
ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7518
7519
7520
if (pmlmepriv->wps_assoc_resp_ie) {
7521
rtw_mfree(pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
7522
pmlmepriv->wps_assoc_resp_ie = NULL;
7523
}
7524
7525
if (ie_len > 0) {
7526
pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
7527
pmlmepriv->wps_assoc_resp_ie_len = ie_len;
7528
if (pmlmepriv->wps_assoc_resp_ie == NULL) {
7529
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7530
return -EINVAL;
7531
}
7532
7533
_rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, param->u.bcn_ie.buf, ie_len);
7534
}
7535
7536
7537
return ret;
7538
7539
}
7540
7541
static int rtw_set_hidden_ssid(struct net_device *dev, struct ieee_param *param, int len)
7542
{
7543
int ret = 0;
7544
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
7545
struct mlme_priv *mlmepriv = &(adapter->mlmepriv);
7546
struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
7547
struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
7548
int ie_len;
7549
u8 *ssid_ie;
7550
char ssid[NDIS_802_11_LENGTH_SSID + 1];
7551
sint ssid_len = 0;
7552
u8 ignore_broadcast_ssid;
7553
7554
if (check_fwstate(mlmepriv, WIFI_AP_STATE) != _TRUE)
7555
return -EPERM;
7556
7557
if (param->u.bcn_ie.reserved[0] != 0xea)
7558
return -EINVAL;
7559
7560
mlmeinfo->hidden_ssid_mode = ignore_broadcast_ssid = param->u.bcn_ie.reserved[1];
7561
7562
ie_len = len - 12 - 2; /* 12 = param header, 2:no packed */
7563
ssid_ie = rtw_get_ie(param->u.bcn_ie.buf, WLAN_EID_SSID, &ssid_len, ie_len);
7564
7565
if (ssid_ie && ssid_len > 0 && ssid_len <= NDIS_802_11_LENGTH_SSID) {
7566
WLAN_BSSID_EX *pbss_network = &mlmepriv->cur_network.network;
7567
WLAN_BSSID_EX *pbss_network_ext = &mlmeinfo->network;
7568
7569
_rtw_memcpy(ssid, ssid_ie + 2, ssid_len);
7570
ssid[ssid_len] = 0x0;
7571
7572
if (0)
7573
RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%d), from ie:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7574
ssid, ssid_len,
7575
pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7576
pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7577
7578
_rtw_memcpy(pbss_network->Ssid.Ssid, (void *)ssid, ssid_len);
7579
pbss_network->Ssid.SsidLength = ssid_len;
7580
_rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)ssid, ssid_len);
7581
pbss_network_ext->Ssid.SsidLength = ssid_len;
7582
7583
if (0)
7584
RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
7585
pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
7586
pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
7587
}
7588
7589
RTW_INFO(FUNC_ADPT_FMT" ignore_broadcast_ssid:%d, %s,%d\n", FUNC_ADPT_ARG(adapter),
7590
ignore_broadcast_ssid, ssid, ssid_len);
7591
7592
return ret;
7593
}
7594
7595
#if CONFIG_RTW_MACADDR_ACL
7596
static int rtw_ioctl_acl_remove_sta(struct net_device *dev, struct ieee_param *param, int len)
7597
{
7598
int ret = 0;
7599
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7600
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7601
7602
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7603
return -EINVAL;
7604
7605
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7606
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7607
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7608
return -EINVAL;
7609
7610
ret = rtw_acl_remove_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);
7611
7612
return ret;
7613
7614
}
7615
7616
static int rtw_ioctl_acl_add_sta(struct net_device *dev, struct ieee_param *param, int len)
7617
{
7618
int ret = 0;
7619
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7620
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7621
7622
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7623
return -EINVAL;
7624
7625
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
7626
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
7627
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff)
7628
return -EINVAL;
7629
7630
ret = rtw_acl_add_sta(padapter, RTW_ACL_PERIOD_BSS, param->sta_addr);
7631
7632
return ret;
7633
7634
}
7635
7636
static int rtw_ioctl_set_macaddr_acl(struct net_device *dev, struct ieee_param *param, int len)
7637
{
7638
int ret = 0;
7639
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7640
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7641
7642
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
7643
return -EINVAL;
7644
7645
rtw_set_macaddr_acl(padapter, RTW_ACL_PERIOD_BSS, param->u.mlme.command);
7646
7647
return ret;
7648
}
7649
#endif /* CONFIG_RTW_MACADDR_ACL */
7650
7651
static int rtw_hostapd_ioctl(struct net_device *dev, struct iw_point *p)
7652
{
7653
struct ieee_param *param;
7654
int ret = 0;
7655
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7656
7657
/* RTW_INFO("%s\n", __FUNCTION__); */
7658
7659
/*
7660
* this function is expect to call in master mode, which allows no power saving
7661
* so, we just check hw_init_completed
7662
*/
7663
7664
if (!rtw_is_hw_init_completed(padapter)) {
7665
ret = -EPERM;
7666
goto out;
7667
}
7668
7669
7670
/* if (p->length < sizeof(struct ieee_param) || !p->pointer){ */
7671
if (!p->pointer) {
7672
ret = -EINVAL;
7673
goto out;
7674
}
7675
7676
param = (struct ieee_param *)rtw_malloc(p->length);
7677
if (param == NULL) {
7678
ret = -ENOMEM;
7679
goto out;
7680
}
7681
7682
if (copy_from_user(param, p->pointer, p->length)) {
7683
rtw_mfree((u8 *)param, p->length);
7684
ret = -EFAULT;
7685
goto out;
7686
}
7687
7688
/* RTW_INFO("%s, cmd=%d\n", __FUNCTION__, param->cmd); */
7689
7690
switch (param->cmd) {
7691
case RTL871X_HOSTAPD_FLUSH:
7692
7693
ret = rtw_hostapd_sta_flush(dev);
7694
7695
break;
7696
7697
case RTL871X_HOSTAPD_ADD_STA:
7698
7699
ret = rtw_add_sta(dev, param);
7700
7701
break;
7702
7703
case RTL871X_HOSTAPD_REMOVE_STA:
7704
7705
ret = rtw_del_sta(dev, param);
7706
7707
break;
7708
7709
case RTL871X_HOSTAPD_SET_BEACON:
7710
7711
ret = rtw_set_beacon(dev, param, p->length);
7712
7713
break;
7714
7715
case RTL871X_SET_ENCRYPTION:
7716
7717
ret = rtw_set_encryption(dev, param, p->length);
7718
7719
break;
7720
7721
case RTL871X_HOSTAPD_GET_WPAIE_STA:
7722
7723
ret = rtw_get_sta_wpaie(dev, param);
7724
7725
break;
7726
7727
case RTL871X_HOSTAPD_SET_WPS_BEACON:
7728
7729
ret = rtw_set_wps_beacon(dev, param, p->length);
7730
7731
break;
7732
7733
case RTL871X_HOSTAPD_SET_WPS_PROBE_RESP:
7734
7735
ret = rtw_set_wps_probe_resp(dev, param, p->length);
7736
7737
break;
7738
7739
case RTL871X_HOSTAPD_SET_WPS_ASSOC_RESP:
7740
7741
ret = rtw_set_wps_assoc_resp(dev, param, p->length);
7742
7743
break;
7744
7745
case RTL871X_HOSTAPD_SET_HIDDEN_SSID:
7746
7747
ret = rtw_set_hidden_ssid(dev, param, p->length);
7748
7749
break;
7750
7751
case RTL871X_HOSTAPD_GET_INFO_STA:
7752
7753
ret = rtw_ioctl_get_sta_data(dev, param, p->length);
7754
7755
break;
7756
7757
#if CONFIG_RTW_MACADDR_ACL
7758
case RTL871X_HOSTAPD_SET_MACADDR_ACL:
7759
ret = rtw_ioctl_set_macaddr_acl(dev, param, p->length);
7760
break;
7761
case RTL871X_HOSTAPD_ACL_ADD_STA:
7762
ret = rtw_ioctl_acl_add_sta(dev, param, p->length);
7763
break;
7764
case RTL871X_HOSTAPD_ACL_REMOVE_STA:
7765
ret = rtw_ioctl_acl_remove_sta(dev, param, p->length);
7766
break;
7767
#endif /* CONFIG_RTW_MACADDR_ACL */
7768
7769
default:
7770
RTW_INFO("Unknown hostapd request: %d\n", param->cmd);
7771
ret = -EOPNOTSUPP;
7772
break;
7773
7774
}
7775
7776
if (ret == 0 && copy_to_user(p->pointer, param, p->length))
7777
ret = -EFAULT;
7778
7779
7780
rtw_mfree((u8 *)param, p->length);
7781
7782
out:
7783
7784
return ret;
7785
7786
}
7787
#endif
7788
7789
static int rtw_wx_set_priv(struct net_device *dev,
7790
struct iw_request_info *info,
7791
union iwreq_data *awrq,
7792
char *extra)
7793
{
7794
7795
#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7796
char *ext_dbg;
7797
#endif
7798
7799
int ret = 0;
7800
int len = 0;
7801
char *ext;
7802
#ifdef CONFIG_ANDROID
7803
int i;
7804
#endif
7805
7806
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7807
struct iw_point *dwrq = (struct iw_point *)awrq;
7808
7809
if (dwrq->length == 0)
7810
return -EFAULT;
7811
7812
len = dwrq->length;
7813
ext = rtw_vmalloc(len);
7814
if (!ext)
7815
return -ENOMEM;
7816
7817
if (copy_from_user(ext, dwrq->pointer, len)) {
7818
rtw_vmfree(ext, len);
7819
return -EFAULT;
7820
}
7821
7822
7823
7824
#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7825
ext_dbg = rtw_vmalloc(len);
7826
if (!ext_dbg) {
7827
rtw_vmfree(ext, len);
7828
return -ENOMEM;
7829
}
7830
7831
_rtw_memcpy(ext_dbg, ext, len);
7832
#endif
7833
7834
/* added for wps2.0 @20110524 */
7835
if (dwrq->flags == 0x8766 && len > 8) {
7836
u32 cp_sz;
7837
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7838
u8 *probereq_wpsie = ext;
7839
int probereq_wpsie_len = len;
7840
u8 wps_oui[4] = {0x0, 0x50, 0xf2, 0x04};
7841
7842
if ((_VENDOR_SPECIFIC_IE_ == probereq_wpsie[0]) &&
7843
(_rtw_memcmp(&probereq_wpsie[2], wps_oui, 4) == _TRUE)) {
7844
cp_sz = probereq_wpsie_len > MAX_WPS_IE_LEN ? MAX_WPS_IE_LEN : probereq_wpsie_len;
7845
7846
if (pmlmepriv->wps_probe_req_ie) {
7847
u32 free_len = pmlmepriv->wps_probe_req_ie_len;
7848
pmlmepriv->wps_probe_req_ie_len = 0;
7849
rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
7850
pmlmepriv->wps_probe_req_ie = NULL;
7851
}
7852
7853
pmlmepriv->wps_probe_req_ie = rtw_malloc(cp_sz);
7854
if (pmlmepriv->wps_probe_req_ie == NULL) {
7855
printk("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
7856
ret = -EINVAL;
7857
goto FREE_EXT;
7858
7859
}
7860
7861
_rtw_memcpy(pmlmepriv->wps_probe_req_ie, probereq_wpsie, cp_sz);
7862
pmlmepriv->wps_probe_req_ie_len = cp_sz;
7863
7864
}
7865
7866
goto FREE_EXT;
7867
7868
}
7869
7870
if (len >= WEXT_CSCAN_HEADER_SIZE
7871
&& _rtw_memcmp(ext, WEXT_CSCAN_HEADER, WEXT_CSCAN_HEADER_SIZE) == _TRUE
7872
) {
7873
ret = rtw_wx_set_scan(dev, info, awrq, ext);
7874
goto FREE_EXT;
7875
}
7876
7877
#ifdef CONFIG_ANDROID
7878
/* RTW_INFO("rtw_wx_set_priv: %s req=%s\n", dev->name, ext); */
7879
7880
i = rtw_android_cmdstr_to_num(ext);
7881
7882
switch (i) {
7883
case ANDROID_WIFI_CMD_START:
7884
indicate_wx_custom_event(padapter, "START");
7885
break;
7886
case ANDROID_WIFI_CMD_STOP:
7887
indicate_wx_custom_event(padapter, "STOP");
7888
break;
7889
case ANDROID_WIFI_CMD_RSSI: {
7890
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7891
struct wlan_network *pcur_network = &pmlmepriv->cur_network;
7892
7893
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
7894
sprintf(ext, "%s rssi %d", pcur_network->network.Ssid.Ssid, padapter->recvpriv.rssi);
7895
else
7896
sprintf(ext, "OK");
7897
}
7898
break;
7899
case ANDROID_WIFI_CMD_LINKSPEED: {
7900
u16 mbps = rtw_get_cur_max_rate(padapter) / 10;
7901
sprintf(ext, "LINKSPEED %d", mbps);
7902
}
7903
break;
7904
case ANDROID_WIFI_CMD_MACADDR:
7905
sprintf(ext, "MACADDR = " MAC_FMT, MAC_ARG(dev->dev_addr));
7906
break;
7907
case ANDROID_WIFI_CMD_SCAN_ACTIVE: {
7908
/* rtw_set_scan_mode(padapter, SCAN_ACTIVE); */
7909
sprintf(ext, "OK");
7910
}
7911
break;
7912
case ANDROID_WIFI_CMD_SCAN_PASSIVE: {
7913
/* rtw_set_scan_mode(padapter, SCAN_PASSIVE); */
7914
sprintf(ext, "OK");
7915
}
7916
break;
7917
7918
case ANDROID_WIFI_CMD_COUNTRY: {
7919
char country_code[10];
7920
sscanf(ext, "%*s %s", country_code);
7921
rtw_set_country(padapter, country_code);
7922
sprintf(ext, "OK");
7923
}
7924
break;
7925
default:
7926
#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7927
RTW_INFO("%s: %s unknowned req=%s\n", __FUNCTION__,
7928
dev->name, ext_dbg);
7929
#endif
7930
7931
sprintf(ext, "OK");
7932
7933
}
7934
7935
if (copy_to_user(dwrq->pointer, ext, min(dwrq->length, (u16)(strlen(ext) + 1))))
7936
ret = -EFAULT;
7937
7938
#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7939
RTW_INFO("%s: %s req=%s rep=%s dwrq->length=%d, strlen(ext)+1=%d\n", __FUNCTION__,
7940
dev->name, ext_dbg , ext, dwrq->length, (u16)(strlen(ext) + 1));
7941
#endif
7942
#endif /* end of CONFIG_ANDROID */
7943
7944
7945
FREE_EXT:
7946
7947
rtw_vmfree(ext, len);
7948
#ifdef CONFIG_DEBUG_RTW_WX_SET_PRIV
7949
rtw_vmfree(ext_dbg, len);
7950
#endif
7951
7952
/* RTW_INFO("rtw_wx_set_priv: (SIOCSIWPRIV) %s ret=%d\n", */
7953
/* dev->name, ret); */
7954
7955
return ret;
7956
7957
}
7958
#ifdef CONFIG_WOWLAN
7959
static int rtw_wowlan_ctrl(struct net_device *dev,
7960
struct iw_request_info *info,
7961
union iwreq_data *wrqu, char *extra)
7962
{
7963
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
7964
struct wowlan_ioctl_param poidparam;
7965
struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
7966
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
7967
int ret = 0;
7968
systime start_time = rtw_get_current_time();
7969
poidparam.subcode = 0;
7970
7971
RTW_INFO("+rtw_wowlan_ctrl: %s\n", extra);
7972
7973
if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
7974
check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
7975
!WOWLAN_IS_STA_MIX_MODE(padapter)) {
7976
#ifdef CONFIG_PNO_SUPPORT
7977
pwrctrlpriv->wowlan_pno_enable = _TRUE;
7978
#else
7979
RTW_INFO("[%s] WARNING: Please Connect With AP First!!\n", __func__);
7980
goto _rtw_wowlan_ctrl_exit_free;
7981
#endif /* CONFIG_PNO_SUPPORT */
7982
}
7983
7984
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY))
7985
rtw_scan_abort(padapter);
7986
7987
if (_rtw_memcmp(extra, "enable", 6))
7988
7989
7990
rtw_suspend_common(padapter);
7991
7992
else if (_rtw_memcmp(extra, "disable", 7)) {
7993
#ifdef CONFIG_USB_HCI
7994
RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
7995
RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
7996
#endif
7997
rtw_resume_common(padapter);
7998
7999
#ifdef CONFIG_PNO_SUPPORT
8000
pwrctrlpriv->wowlan_pno_enable = _FALSE;
8001
#endif /* CONFIG_PNO_SUPPORT */
8002
8003
} else {
8004
RTW_INFO("[%s] Invalid Parameter.\n", __func__);
8005
goto _rtw_wowlan_ctrl_exit_free;
8006
}
8007
/* mutex_lock(&ioctl_mutex); */
8008
_rtw_wowlan_ctrl_exit_free:
8009
RTW_INFO("-rtw_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8010
RTW_PRINT("%s in %d ms\n", __func__,
8011
rtw_get_passing_time_ms(start_time));
8012
return ret;
8013
}
8014
8015
/*
8016
* IP filter This pattern if for a frame containing a ip packet:
8017
* AA:AA:AA:AA:AA:AA:BB:BB:BB:BB:BB:BB:CC:CC:DD:-:-:-:-:-:-:-:-:EE:-:-:FF:FF:FF:FF:GG:GG:GG:GG:HH:HH:II:II
8018
*
8019
* A: Ethernet destination address
8020
* B: Ethernet source address
8021
* C: Ethernet protocol type
8022
* D: IP header VER+Hlen, use: 0x45 (4 is for ver 4, 5 is for len 20)
8023
* E: IP protocol
8024
* F: IP source address ( 192.168.0.4: C0:A8:00:2C )
8025
* G: IP destination address ( 192.168.0.4: C0:A8:00:2C )
8026
* H: Source port (1024: 04:00)
8027
* I: Destination port (1024: 04:00)
8028
*/
8029
8030
static int rtw_wowlan_set_pattern(struct net_device *dev,
8031
struct iw_request_info *info,
8032
union iwreq_data *wrqu, char *extra)
8033
{
8034
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8035
struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
8036
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8037
struct wowlan_ioctl_param poidparam;
8038
int ret = 0;
8039
u8 input[wrqu->data.length];
8040
u8 index = 0;
8041
8042
poidparam.subcode = 0;
8043
8044
if (!check_fwstate(pmlmepriv, _FW_LINKED) &&
8045
check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
8046
ret = -EFAULT;
8047
RTW_INFO("Please Connect With AP First!!\n");
8048
goto _rtw_wowlan_set_pattern_exit;
8049
}
8050
8051
if (wrqu->data.length <= 0) {
8052
ret = -EFAULT;
8053
RTW_INFO("ERROR: parameter length <= 0\n");
8054
goto _rtw_wowlan_set_pattern_exit;
8055
} else {
8056
/* set pattern */
8057
if (copy_from_user(input,
8058
wrqu->data.pointer, wrqu->data.length))
8059
return -EFAULT;
8060
/* leave PS first */
8061
rtw_ps_deny(padapter, PS_DENY_IOCTL);
8062
LeaveAllPowerSaveModeDirect(padapter);
8063
if (strncmp(input, "pattern=", 8) == 0) {
8064
if (pwrpriv->wowlan_pattern_idx >= MAX_WKFM_CAM_NUM) {
8065
RTW_INFO("WARNING: priv-pattern is full(idx: %d)\n",
8066
pwrpriv->wowlan_pattern_idx);
8067
RTW_INFO("WARNING: please clean priv-pattern first\n");
8068
ret = -EINVAL;
8069
goto _rtw_wowlan_set_pattern_exit;
8070
} else {
8071
index = pwrpriv->wowlan_pattern_idx;
8072
ret = rtw_wowlan_parser_pattern_cmd(input,
8073
pwrpriv->patterns[index].content,
8074
&pwrpriv->patterns[index].len,
8075
pwrpriv->patterns[index].mask);
8076
8077
if (ret == _TRUE)
8078
pwrpriv->wowlan_pattern_idx++;
8079
}
8080
} else if (strncmp(input, "clean", 5) == 0) {
8081
poidparam.subcode = WOWLAN_PATTERN_CLEAN;
8082
rtw_hal_set_hwreg(padapter,
8083
HW_VAR_WOWLAN, (u8 *)&poidparam);
8084
} else if (strncmp(input, "show", 4) == 0) {
8085
rtw_wow_pattern_cam_dump(padapter);
8086
rtw_wow_pattern_sw_dump(padapter);
8087
} else {
8088
RTW_INFO("ERROR: incorrect parameter!\n");
8089
ret = -EINVAL;
8090
}
8091
rtw_ps_deny_cancel(padapter, PS_DENY_IOCTL);
8092
}
8093
_rtw_wowlan_set_pattern_exit:
8094
return ret;
8095
}
8096
#endif /* CONFIG_WOWLAN */
8097
8098
#ifdef CONFIG_AP_WOWLAN
8099
static int rtw_ap_wowlan_ctrl(struct net_device *dev,
8100
struct iw_request_info *info,
8101
union iwreq_data *wrqu, char *extra)
8102
{
8103
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8104
struct wowlan_ioctl_param poidparam;
8105
struct pwrctrl_priv *pwrctrlpriv = adapter_to_pwrctl(padapter);
8106
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8107
struct sta_info *psta = NULL;
8108
int ret = 0;
8109
systime start_time = rtw_get_current_time();
8110
poidparam.subcode = 0;
8111
8112
RTW_INFO("+rtw_ap_wowlan_ctrl: %s\n", extra);
8113
8114
if (!check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
8115
RTW_INFO("[%s] It is not AP mode!!\n", __func__);
8116
goto _rtw_ap_wowlan_ctrl_exit_free;
8117
}
8118
8119
if (_rtw_memcmp(extra, "enable", 6)) {
8120
8121
pwrctrlpriv->wowlan_ap_mode = _TRUE;
8122
8123
rtw_suspend_common(padapter);
8124
} else if (_rtw_memcmp(extra, "disable", 7)) {
8125
#ifdef CONFIG_USB_HCI
8126
RTW_ENABLE_FUNC(padapter, DF_RX_BIT);
8127
RTW_ENABLE_FUNC(padapter, DF_TX_BIT);
8128
#endif
8129
rtw_resume_common(padapter);
8130
} else {
8131
RTW_INFO("[%s] Invalid Parameter.\n", __func__);
8132
goto _rtw_ap_wowlan_ctrl_exit_free;
8133
}
8134
/* mutex_lock(&ioctl_mutex); */
8135
_rtw_ap_wowlan_ctrl_exit_free:
8136
RTW_INFO("-rtw_ap_wowlan_ctrl( subcode = %d)\n", poidparam.subcode);
8137
RTW_PRINT("%s in %d ms\n", __func__,
8138
rtw_get_passing_time_ms(start_time));
8139
_rtw_ap_wowlan_ctrl_exit:
8140
return ret;
8141
}
8142
#endif /* CONFIG_AP_WOWLAN */
8143
8144
static int rtw_pm_set(struct net_device *dev,
8145
struct iw_request_info *info,
8146
union iwreq_data *wrqu, char *extra)
8147
{
8148
int ret = 0;
8149
unsigned mode = 0;
8150
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8151
8152
RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
8153
8154
if (_rtw_memcmp(extra, "lps=", 4)) {
8155
sscanf(extra + 4, "%u", &mode);
8156
ret = rtw_pm_set_lps(padapter, mode);
8157
} else if (_rtw_memcmp(extra, "ips=", 4)) {
8158
sscanf(extra + 4, "%u", &mode);
8159
ret = rtw_pm_set_ips(padapter, mode);
8160
} else if (_rtw_memcmp(extra, "lps_level=", 10)) {
8161
if (sscanf(extra + 10, "%u", &mode) > 0)
8162
ret = rtw_pm_set_lps_level(padapter, mode);
8163
#ifdef CONFIG_LPS_1T1R
8164
} else if (_rtw_memcmp(extra, "lps_1t1r=", 9)) {
8165
if (sscanf(extra + 9, "%u", &mode) > 0)
8166
ret = rtw_pm_set_lps_1t1r(padapter, mode);
8167
#endif
8168
}
8169
#ifdef CONFIG_WOWLAN
8170
else if (_rtw_memcmp(extra, "wow_lps=", 8)) {
8171
sscanf(extra + 8, "%u", &mode);
8172
ret = rtw_pm_set_wow_lps(padapter, mode);
8173
} else if (_rtw_memcmp(extra, "wow_lps_level=", 14)) {
8174
if (sscanf(extra + 14, "%u", &mode) > 0)
8175
ret = rtw_pm_set_wow_lps_level(padapter, mode);
8176
#ifdef CONFIG_LPS_1T1R
8177
} else if (_rtw_memcmp(extra, "wow_lps_1t1r=", 13)) {
8178
if (sscanf(extra + 13, "%u", &mode) > 0)
8179
ret = rtw_pm_set_wow_lps_1t1r(padapter, mode);
8180
#endif
8181
}
8182
#endif /* CONFIG_WOWLAN */
8183
else
8184
ret = -EINVAL;
8185
8186
return ret;
8187
}
8188
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8189
8190
int rtw_vendor_ie_get_raw_data(struct net_device *dev, u32 vendor_ie_num,
8191
char *extra, u32 length)
8192
{
8193
int j;
8194
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8195
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8196
u32 vendor_ie_mask = 0;
8197
char *pstring;
8198
8199
if (vendor_ie_num >= WLAN_MAX_VENDOR_IE_NUM) {
8200
RTW_INFO("[%s] only support %d vendor ie\n", __func__ ,
8201
WLAN_MAX_VENDOR_IE_NUM);
8202
return -EFAULT;
8203
}
8204
8205
if (pmlmepriv->vendor_ielen[vendor_ie_num] == 0) {
8206
RTW_INFO("[%s] Fail, vendor_ie_num: %d is not set\n", __func__,
8207
vendor_ie_num);
8208
return -EFAULT;
8209
}
8210
8211
if (length < 2 * pmlmepriv->vendor_ielen[vendor_ie_num] + 5) {
8212
RTW_INFO("[%s] Fail, buffer size is too small\n", __func__);
8213
return -EFAULT;
8214
}
8215
8216
vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8217
_rtw_memset(extra, 0, length);
8218
8219
pstring = extra;
8220
pstring += sprintf(pstring, "%d,%x,", vendor_ie_num, vendor_ie_mask);
8221
8222
for (j = 0; j < pmlmepriv->vendor_ielen[vendor_ie_num]; j++)
8223
pstring += sprintf(pstring, "%02x", pmlmepriv->vendor_ie[vendor_ie_num][j]);
8224
8225
length = pstring - extra;
8226
return length;
8227
}
8228
8229
int rtw_vendor_ie_get_data(struct net_device *dev, int vendor_ie_num, char *extra)
8230
{
8231
int j;
8232
char *pstring;
8233
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8234
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8235
u32 vendor_ie_mask = 0;
8236
__u16 length = 0;
8237
8238
vendor_ie_mask = pmlmepriv->vendor_ie_mask[vendor_ie_num];
8239
pstring = extra;
8240
pstring += sprintf(pstring , "\nVendor IE num %d , Mask:%x " , vendor_ie_num , vendor_ie_mask);
8241
8242
if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8243
pstring += sprintf(pstring , "[Beacon]");
8244
if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8245
pstring += sprintf(pstring , "[Probe Req]");
8246
if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8247
pstring += sprintf(pstring , "[Probe Resp]");
8248
if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8249
pstring += sprintf(pstring , "[Assoc Req]");
8250
if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8251
pstring += sprintf(pstring , "[Assoc Resp]");
8252
#ifdef CONFIG_P2P
8253
if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)
8254
pstring += sprintf(pstring , "[P2P_Probe Req]");
8255
if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)
8256
pstring += sprintf(pstring , "[P2P_Probe Resp]");
8257
#endif
8258
8259
pstring += sprintf(pstring , "\nVendor IE:\n");
8260
for (j = 0 ; j < pmlmepriv->vendor_ielen[vendor_ie_num] ; j++)
8261
pstring += sprintf(pstring , "%02x" , pmlmepriv->vendor_ie[vendor_ie_num][j]);
8262
8263
length = pstring - extra;
8264
return length;
8265
8266
}
8267
8268
int rtw_vendor_ie_get(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8269
{
8270
int ret = 0, vendor_ie_num = 0, cmdlen;
8271
struct iw_point *p;
8272
u8 *ptmp;
8273
8274
p = &wrqu->data;
8275
cmdlen = p->length;
8276
if (0 == cmdlen)
8277
return -EINVAL;
8278
8279
ptmp = (u8 *)rtw_malloc(cmdlen);
8280
if (NULL == ptmp)
8281
return -ENOMEM;
8282
8283
if (copy_from_user(ptmp, p->pointer, cmdlen)) {
8284
ret = -EFAULT;
8285
goto exit;
8286
}
8287
ret = sscanf(ptmp , "%d", &vendor_ie_num);
8288
if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8289
ret = -EFAULT;
8290
goto exit;
8291
}
8292
8293
wrqu->data.length = rtw_vendor_ie_get_data(dev, vendor_ie_num, extra);
8294
8295
exit:
8296
rtw_mfree(ptmp, cmdlen);
8297
8298
return 0;
8299
}
8300
8301
int rtw_vendor_ie_set(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra)
8302
{
8303
int ret = 0, i , len = 0 , totoal_ie_len = 0 , total_ie_len_byte = 0;
8304
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8305
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8306
u32 vendor_ie_mask = 0;
8307
u32 vendor_ie_num = 0;
8308
u32 vendor_ie_mask_max = BIT(WLAN_MAX_VENDOR_IE_MASK_MAX) - 1;
8309
u32 id, elen;
8310
8311
ret = sscanf(extra, "%d,%x,%*s", &vendor_ie_num , &vendor_ie_mask);
8312
if (strrchr(extra , ','))
8313
extra = strrchr(extra , ',') + 1;
8314
else
8315
return -EINVAL;
8316
totoal_ie_len = strlen(extra);
8317
RTW_INFO("[%s] vendor_ie_num = %d , vendor_ie_mask = 0x%x , vendor_ie = %s , len = %d\n", __func__ , vendor_ie_num , vendor_ie_mask , extra , totoal_ie_len);
8318
8319
if (vendor_ie_num > WLAN_MAX_VENDOR_IE_NUM - 1) {
8320
RTW_INFO("[%s] Fail, only support %d vendor ie\n", __func__ , WLAN_MAX_VENDOR_IE_NUM);
8321
return -EFAULT;
8322
}
8323
8324
if (totoal_ie_len > WLAN_MAX_VENDOR_IE_LEN) {
8325
RTW_INFO("[%s] Fail , not support ie length extend %d\n", __func__ , WLAN_MAX_VENDOR_IE_LEN);
8326
return -EFAULT;
8327
}
8328
8329
if (vendor_ie_mask > vendor_ie_mask_max) {
8330
RTW_INFO("[%s] Fail, not support vendor_ie_mask more than 0x%x\n", __func__ , vendor_ie_mask_max);
8331
return -EFAULT;
8332
}
8333
8334
if (vendor_ie_mask == 0) {
8335
RTW_INFO("[%s] Clear vendor_ie_num %d group\n", __func__ , vendor_ie_num);
8336
goto _clear_path;
8337
}
8338
8339
if (totoal_ie_len % 2 != 0) {
8340
RTW_INFO("[%s] Fail , IE length = %zu is odd\n" , __func__ , strlen(extra));
8341
return -EFAULT;
8342
}
8343
8344
if (totoal_ie_len > 0) {
8345
for (i = 0 ; i < strlen(extra) ; i += 2) {
8346
pmlmepriv->vendor_ie[vendor_ie_num][len] = key_2char2num(extra[i] , extra[i + 1]);
8347
if (len == 0) {
8348
id = pmlmepriv->vendor_ie[vendor_ie_num][len];
8349
if (id != WLAN_EID_VENDOR_SPECIFIC) {
8350
RTW_INFO("[%s] Fail , VENDOR SPECIFIC IE ID \"%x\" was not correct\n", __func__ , id);
8351
goto _clear_path;
8352
}
8353
} else if (len == 1) {
8354
total_ie_len_byte = (totoal_ie_len / 2) - 2;
8355
elen = pmlmepriv->vendor_ie[vendor_ie_num][len];
8356
if (elen != total_ie_len_byte) {
8357
RTW_INFO("[%s] Fail , Input IE length = \"%d\"(hex:%x) bytes , not match input total IE context length \"%d\" bytes\n", __func__ , elen , elen ,
8358
total_ie_len_byte);
8359
goto _clear_path;
8360
}
8361
}
8362
len++;
8363
}
8364
pmlmepriv->vendor_ielen[vendor_ie_num] = len;
8365
} else
8366
pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
8367
8368
8369
8370
if (vendor_ie_mask & WIFI_BEACON_VENDOR_IE_BIT)
8371
RTW_INFO("[%s] Beacon append vendor ie\n", __func__);
8372
if (vendor_ie_mask & WIFI_PROBEREQ_VENDOR_IE_BIT)
8373
RTW_INFO("[%s] Probe Req append vendor ie\n", __func__);
8374
if (vendor_ie_mask & WIFI_PROBERESP_VENDOR_IE_BIT)
8375
RTW_INFO("[%s] Probe Resp append vendor ie\n", __func__);
8376
if (vendor_ie_mask & WIFI_ASSOCREQ_VENDOR_IE_BIT)
8377
RTW_INFO("[%s] Assoc Req append vendor ie\n", __func__);
8378
if (vendor_ie_mask & WIFI_ASSOCRESP_VENDOR_IE_BIT)
8379
RTW_INFO("[%s] Assoc Resp append vendor ie\n", __func__);
8380
#ifdef CONFIG_P2P
8381
if (vendor_ie_mask & WIFI_P2P_PROBEREQ_VENDOR_IE_BIT)
8382
RTW_INFO("[%s] P2P Probe Req append vendor ie\n", __func__);
8383
if (vendor_ie_mask & WIFI_P2P_PROBERESP_VENDOR_IE_BIT)
8384
RTW_INFO("[%s] P2P Probe Resp append vendor ie\n", __func__);
8385
#endif
8386
8387
pmlmepriv->vendor_ie_mask[vendor_ie_num] = vendor_ie_mask;
8388
8389
return ret;
8390
8391
_clear_path:
8392
_rtw_memset(pmlmepriv->vendor_ie[vendor_ie_num] , 0 , sizeof(u32) * WLAN_MAX_VENDOR_IE_LEN);
8393
pmlmepriv->vendor_ielen[vendor_ie_num] = 0;
8394
pmlmepriv->vendor_ie_mask[vendor_ie_num] = 0;
8395
return -EFAULT;
8396
}
8397
#endif
8398
8399
static int rtw_mp_efuse_get(struct net_device *dev,
8400
struct iw_request_info *info,
8401
union iwreq_data *wdata, char *extra)
8402
{
8403
PADAPTER padapter = rtw_netdev_priv(dev);
8404
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
8405
8406
PEFUSE_HAL pEfuseHal;
8407
struct iw_point *wrqu;
8408
8409
u8 ips_mode = IPS_NUM; /* init invalid value */
8410
u8 lps_mode = PS_MODE_NUM; /* init invalid value */
8411
struct pwrctrl_priv *pwrctrlpriv ;
8412
u8 *data = NULL;
8413
u8 *rawdata = NULL;
8414
char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
8415
u16 i = 0, j = 0, mapLen = 0, addr = 0, cnts = 0;
8416
u16 max_available_len = 0, raw_cursize = 0, raw_maxsize = 0;
8417
u16 mask_len;
8418
u8 mask_buf[64] = "";
8419
int err;
8420
char *pextra = NULL;
8421
#ifdef CONFIG_IOL
8422
u8 org_fw_iol = padapter->registrypriv.fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
8423
#endif
8424
8425
wrqu = (struct iw_point *)wdata;
8426
pwrctrlpriv = adapter_to_pwrctl(padapter);
8427
pEfuseHal = &pHalData->EfuseHal;
8428
8429
err = 0;
8430
data = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
8431
if (data == NULL) {
8432
err = -ENOMEM;
8433
goto exit;
8434
}
8435
rawdata = rtw_zmalloc(EFUSE_BT_MAX_MAP_LEN);
8436
if (rawdata == NULL) {
8437
err = -ENOMEM;
8438
goto exit;
8439
}
8440
8441
if (copy_from_user(extra, wrqu->pointer, wrqu->length)) {
8442
err = -EFAULT;
8443
goto exit;
8444
}
8445
8446
*(extra + wrqu->length) = '\0';
8447
8448
#ifdef CONFIG_LPS
8449
lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
8450
rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
8451
#endif
8452
8453
#ifdef CONFIG_IPS
8454
ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
8455
rtw_pm_set_ips(padapter, IPS_NONE);
8456
#endif
8457
8458
pch = extra;
8459
RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
8460
8461
i = 0;
8462
/* mac 16 "00e04c871200" rmap,00,2 */
8463
while ((token = strsep(&pch, ",")) != NULL) {
8464
if (i > 2)
8465
break;
8466
tmp[i] = token;
8467
i++;
8468
}
8469
#ifdef CONFIG_IOL
8470
padapter->registrypriv.fw_iol = 0;/* 0:Disable, 1:enable, 2:by usb speed */
8471
#endif
8472
8473
if (strcmp(tmp[0], "status") == 0) {
8474
sprintf(extra, "Load File efuse=%s,Load File MAC=%s"
8475
, pHalData->efuse_file_status == EFUSE_FILE_FAILED ? "FAIL" : "OK"
8476
, pHalData->macaddr_file_status == MACADDR_FILE_FAILED ? "FAIL" : "OK"
8477
);
8478
goto exit;
8479
} else if (strcmp(tmp[0], "drvmap") == 0) {
8480
static u8 drvmaporder = 0;
8481
u8 *efuse;
8482
u32 shift, cnt;
8483
u32 blksz = 0x200; /* The size of one time show, default 512 */
8484
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&mapLen, _FALSE);
8485
8486
efuse = pHalData->efuse_eeprom_data;
8487
8488
shift = blksz * drvmaporder;
8489
efuse += shift;
8490
cnt = mapLen - shift;
8491
8492
if (cnt > blksz) {
8493
cnt = blksz;
8494
drvmaporder++;
8495
} else
8496
drvmaporder = 0;
8497
8498
sprintf(extra, "\n");
8499
for (i = 0; i < cnt; i += 16) {
8500
pextra = extra + strlen(extra);
8501
pextra += sprintf(pextra, "0x%02x\t", shift + i);
8502
for (j = 0; j < 8; j++)
8503
pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8504
pextra += sprintf(pextra, "\t");
8505
for (; j < 16; j++)
8506
pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8507
pextra += sprintf(pextra, "\n");
8508
}
8509
if ((shift + cnt) < mapLen)
8510
pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8511
8512
} else if (strcmp(tmp[0], "realmap") == 0) {
8513
static u8 order = 0;
8514
u8 *efuse;
8515
u32 shift, cnt;
8516
u32 blksz = 0x200; /* The size of one time show, default 512 */
8517
8518
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
8519
efuse = pEfuseHal->fakeEfuseInitMap;
8520
if (rtw_efuse_mask_map_read(padapter, 0, mapLen, efuse) == _FAIL) {
8521
RTW_INFO("%s: read realmap Fail!!\n", __FUNCTION__);
8522
err = -EFAULT;
8523
goto exit;
8524
}
8525
8526
#if 0
8527
RTW_INFO("OFFSET\tVALUE(hex)\n");
8528
for (i = 0; i < mapLen; i += 16) {
8529
RTW_INFO("0x%02x\t", i);
8530
for (j = 0; j < 8; j++)
8531
RTW_INFO("%02X ", efuse[i + j]);
8532
RTW_INFO("\t");
8533
for (; j < 16; j++)
8534
RTW_INFO("%02X ", efuse[i + j]);
8535
RTW_INFO("\n");
8536
}
8537
RTW_INFO("\n");
8538
#endif
8539
8540
shift = blksz * order;
8541
efuse += shift;
8542
cnt = mapLen - shift;
8543
if (cnt > blksz) {
8544
cnt = blksz;
8545
order++;
8546
} else
8547
order = 0;
8548
8549
sprintf(extra, "\n");
8550
for (i = 0; i < cnt; i += 16) {
8551
pextra = extra + strlen(extra);
8552
pextra += sprintf(pextra, "0x%02x\t", shift + i);
8553
for (j = 0; j < 8; j++)
8554
pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8555
pextra += sprintf(pextra, "\t");
8556
for (; j < 16; j++)
8557
pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8558
pextra += sprintf(pextra, "\n");
8559
}
8560
if ((shift + cnt) < mapLen)
8561
pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8562
} else if (strcmp(tmp[0], "rmap") == 0) {
8563
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8564
RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
8565
err = -EINVAL;
8566
goto exit;
8567
}
8568
8569
/* rmap addr cnts */
8570
addr = simple_strtoul(tmp[1], &ptmp, 16);
8571
RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
8572
8573
cnts = simple_strtoul(tmp[2], &ptmp, 10);
8574
if (cnts == 0) {
8575
RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
8576
err = -EINVAL;
8577
goto exit;
8578
}
8579
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
8580
8581
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&max_available_len, _FALSE);
8582
if ((addr + cnts) > max_available_len) {
8583
RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8584
err = -EINVAL;
8585
goto exit;
8586
}
8587
8588
if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8589
RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
8590
err = -EFAULT;
8591
goto exit;
8592
}
8593
8594
/* RTW_INFO("%s: data={", __FUNCTION__); */
8595
*extra = 0;
8596
pextra = extra;
8597
for (i = 0; i < cnts; i++) {
8598
/* RTW_INFO("0x%02x ", data[i]); */
8599
pextra += sprintf(pextra, "0x%02X ", data[i]);
8600
}
8601
/* RTW_INFO("}\n"); */
8602
} else if (strcmp(tmp[0], "realraw") == 0) {
8603
static u8 raw_order = 0;
8604
u32 shift, cnt;
8605
u32 blksz = 0x200; /* The size of one time show, default 512 */
8606
8607
addr = 0;
8608
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_REAL_CONTENT_LEN , (void *)&mapLen, _FALSE);
8609
RTW_INFO("Real content len = %d\n",mapLen );
8610
8611
if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
8612
RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8613
err = -EFAULT;
8614
goto exit;
8615
}
8616
8617
_rtw_memset(extra, '\0', strlen(extra));
8618
8619
shift = blksz * raw_order;
8620
rawdata += shift;
8621
cnt = mapLen - shift;
8622
if (cnt > blksz) {
8623
cnt = blksz;
8624
raw_order++;
8625
} else
8626
raw_order = 0;
8627
8628
sprintf(extra, "\n");
8629
for (i = 0; i < cnt; i += 16) {
8630
pextra = extra + strlen(extra);
8631
pextra += sprintf(pextra, "0x%02x\t", shift + i);
8632
for (j = 0; j < 8; j++)
8633
pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8634
pextra += sprintf(pextra, "\t");
8635
for (; j < 16; j++)
8636
pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8637
pextra += sprintf(pextra, "\n");
8638
}
8639
if ((shift + cnt) < mapLen)
8640
pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8641
8642
} else if (strcmp(tmp[0], "btrealraw") == 0) {
8643
static u8 bt_raw_order = 0;
8644
u32 shift, cnt;
8645
u32 blksz = 0x200; /* The size of one time show, default 512 */
8646
8647
addr = 0;
8648
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_REAL_CONTENT_LEN, (void *)&mapLen, _FALSE);
8649
RTW_INFO("Real content len = %d\n", mapLen);
8650
#ifdef RTW_HALMAC
8651
if (rtw_efuse_bt_access(padapter, _FALSE, 0, mapLen, rawdata) == _FAIL) {
8652
RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8653
err = -EFAULT;
8654
goto exit;
8655
}
8656
#else
8657
rtw_write8(padapter, 0x35, 0x1);
8658
8659
if (rtw_efuse_access(padapter, _FALSE, addr, mapLen, rawdata) == _FAIL) {
8660
RTW_INFO("%s: rtw_efuse_access Fail!!\n", __func__);
8661
err = -EFAULT;
8662
goto exit;
8663
}
8664
#endif
8665
_rtw_memset(extra, '\0', strlen(extra));
8666
8667
shift = blksz * bt_raw_order;
8668
rawdata += shift;
8669
cnt = mapLen - shift;
8670
if (cnt > blksz) {
8671
cnt = blksz;
8672
bt_raw_order++;
8673
} else
8674
bt_raw_order = 0;
8675
8676
sprintf(extra, "\n");
8677
for (i = 0; i < cnt; i += 16) {
8678
pextra = extra + strlen(extra);
8679
pextra += sprintf(pextra, "0x%02x\t", shift + i);
8680
for (j = 0; j < 8; j++)
8681
pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8682
pextra += sprintf(pextra, "\t");
8683
for (; j < 16; j++)
8684
pextra += sprintf(pextra, "%02X ", rawdata[i + j]);
8685
pextra += sprintf(pextra, "\n");
8686
}
8687
if ((shift + cnt) < mapLen)
8688
pextra += sprintf(pextra, "\t...more (left:%d/%d)\n", mapLen-(shift + cnt), mapLen);
8689
8690
} else if (strcmp(tmp[0], "mac") == 0) {
8691
if (hal_efuse_macaddr_offset(padapter) == -1) {
8692
err = -EFAULT;
8693
goto exit;
8694
}
8695
8696
addr = hal_efuse_macaddr_offset(padapter);
8697
cnts = 6;
8698
8699
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8700
if ((addr + cnts) > max_available_len) {
8701
RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8702
err = -EFAULT;
8703
goto exit;
8704
}
8705
8706
if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8707
RTW_INFO("%s: rtw_efuse_mask_map_read error!\n", __func__);
8708
err = -EFAULT;
8709
goto exit;
8710
}
8711
8712
/* RTW_INFO("%s: MAC address={", __FUNCTION__); */
8713
*extra = 0;
8714
pextra = extra;
8715
for (i = 0; i < cnts; i++) {
8716
/* RTW_INFO("%02X", data[i]); */
8717
pextra += sprintf(pextra, "%02X", data[i]);
8718
if (i != (cnts - 1)) {
8719
/* RTW_INFO(":"); */
8720
pextra += sprintf(pextra, ":");
8721
}
8722
}
8723
/* RTW_INFO("}\n"); */
8724
} else if (strcmp(tmp[0], "vidpid") == 0) {
8725
#ifdef CONFIG_RTL8188E
8726
#ifdef CONFIG_USB_HCI
8727
addr = EEPROM_VID_88EU;
8728
#endif
8729
#ifdef CONFIG_PCI_HCI
8730
addr = EEPROM_VID_88EE;
8731
#endif
8732
#endif /* CONFIG_RTL8188E */
8733
8734
#ifdef CONFIG_RTL8192E
8735
#ifdef CONFIG_USB_HCI
8736
addr = EEPROM_VID_8192EU;
8737
#endif
8738
#ifdef CONFIG_PCI_HCI
8739
addr = EEPROM_VID_8192EE;
8740
#endif
8741
#endif /* CONFIG_RTL8192E */
8742
#ifdef CONFIG_RTL8723B
8743
addr = EEPROM_VID_8723BU;
8744
#endif /* CONFIG_RTL8192E */
8745
8746
#ifdef CONFIG_RTL8188F
8747
addr = EEPROM_VID_8188FU;
8748
#endif /* CONFIG_RTL8188F */
8749
8750
#ifdef CONFIG_RTL8188GTV
8751
addr = EEPROM_VID_8188GTVU;
8752
#endif
8753
8754
#ifdef CONFIG_RTL8703B
8755
#ifdef CONFIG_USB_HCI
8756
addr = EEPROM_VID_8703BU;
8757
#endif
8758
#endif /* CONFIG_RTL8703B */
8759
8760
#ifdef CONFIG_RTL8723D
8761
#ifdef CONFIG_USB_HCI
8762
addr = EEPROM_VID_8723DU;
8763
#endif /* CONFIG_USB_HCI */
8764
#endif /* CONFIG_RTL8723D */
8765
8766
cnts = 4;
8767
8768
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8769
if ((addr + cnts) > max_available_len) {
8770
RTW_INFO("%s: addr(0x%02x)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8771
err = -EFAULT;
8772
goto exit;
8773
}
8774
if (rtw_efuse_mask_map_read(padapter, addr, cnts, data) == _FAIL) {
8775
RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
8776
err = -EFAULT;
8777
goto exit;
8778
}
8779
8780
/* RTW_INFO("%s: {VID,PID}={", __FUNCTION__); */
8781
*extra = 0;
8782
pextra = extra;
8783
for (i = 0; i < cnts; i++) {
8784
/* RTW_INFO("0x%02x", data[i]); */
8785
pextra += sprintf(pextra, "0x%02X", data[i]);
8786
if (i != (cnts - 1)) {
8787
/* RTW_INFO(","); */
8788
pextra += sprintf(pextra, ",");
8789
}
8790
}
8791
/* RTW_INFO("}\n"); */
8792
} else if (strcmp(tmp[0], "ableraw") == 0) {
8793
#ifdef RTW_HALMAC
8794
raw_maxsize = efuse_GetavailableSize(padapter);
8795
#else
8796
efuse_GetCurrentSize(padapter, &raw_cursize);
8797
raw_maxsize = efuse_GetMaxSize(padapter);
8798
#endif
8799
sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
8800
} else if (strcmp(tmp[0], "btableraw") == 0) {
8801
efuse_bt_GetCurrentSize(padapter, &raw_cursize);
8802
raw_maxsize = efuse_bt_GetMaxSize(padapter);
8803
sprintf(extra, "[available raw size]= %d bytes\n", raw_maxsize - raw_cursize);
8804
} else if (strcmp(tmp[0], "btfmap") == 0) {
8805
8806
BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8807
8808
mapLen = EFUSE_BT_MAX_MAP_LEN;
8809
if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
8810
RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
8811
err = -EFAULT;
8812
goto exit;
8813
}
8814
8815
/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8816
sprintf(extra, "\n");
8817
for (i = 0; i < 512; i += 16) { /* set 512 because the iwpriv's extra size have limit 0x7FF */
8818
/* RTW_INFO("0x%03x\t", i); */
8819
pextra = extra + strlen(extra);
8820
pextra += sprintf(pextra, "0x%03x\t", i);
8821
for (j = 0; j < 8; j++) {
8822
/* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
8823
pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8824
}
8825
/* RTW_INFO("\t"); */
8826
pextra += sprintf(pextra, "\t");
8827
for (; j < 16; j++) {
8828
/* RTW_INFO("%02X ", pEfuseHal->BTEfuseInitMap[i+j]); */
8829
pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8830
}
8831
/* RTW_INFO("\n"); */
8832
pextra += sprintf(pextra, "\n");
8833
}
8834
/* RTW_INFO("\n"); */
8835
} else if (strcmp(tmp[0], "btbmap") == 0) {
8836
BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8837
8838
mapLen = EFUSE_BT_MAX_MAP_LEN;
8839
if (rtw_BT_efuse_map_read(padapter, 0, mapLen, pEfuseHal->BTEfuseInitMap) == _FAIL) {
8840
RTW_INFO("%s: rtw_BT_efuse_map_read Fail!!\n", __FUNCTION__);
8841
err = -EFAULT;
8842
goto exit;
8843
}
8844
8845
/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8846
sprintf(extra, "\n");
8847
for (i = 512; i < 1024 ; i += 16) {
8848
/* RTW_INFO("0x%03x\t", i); */
8849
pextra = extra + strlen(extra);
8850
pextra += sprintf(pextra, "0x%03x\t", i);
8851
for (j = 0; j < 8; j++) {
8852
/* RTW_INFO("%02X ", data[i+j]); */
8853
pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8854
}
8855
/* RTW_INFO("\t"); */
8856
pextra += sprintf(pextra, "\t");
8857
for (; j < 16; j++) {
8858
/* RTW_INFO("%02X ", data[i+j]); */
8859
pextra += sprintf(pextra, "%02X ", pEfuseHal->BTEfuseInitMap[i+j]);
8860
}
8861
/* RTW_INFO("\n"); */
8862
pextra += sprintf(pextra, "\n");
8863
}
8864
/* RTW_INFO("\n"); */
8865
} else if (strcmp(tmp[0], "btrmap") == 0) {
8866
u8 BTStatus;
8867
8868
rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
8869
BTStatus = rtw_read8(padapter, 0xa0);
8870
8871
RTW_INFO("%s: Check 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
8872
if (BTStatus != 0x04) {
8873
sprintf(extra, "BT Status not Active ,can't to read BT eFuse\n");
8874
goto exit;
8875
}
8876
8877
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8878
err = -EINVAL;
8879
goto exit;
8880
}
8881
8882
BTEfuse_PowerSwitch(padapter, 1, _TRUE);
8883
8884
/* rmap addr cnts */
8885
addr = simple_strtoul(tmp[1], &ptmp, 16);
8886
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
8887
8888
cnts = simple_strtoul(tmp[2], &ptmp, 10);
8889
if (cnts == 0) {
8890
RTW_INFO("%s: btrmap Fail!! cnts error!\n", __FUNCTION__);
8891
err = -EINVAL;
8892
goto exit;
8893
}
8894
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
8895
#ifndef RTW_HALMAC
8896
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
8897
if ((addr + cnts) > max_available_len) {
8898
RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
8899
err = -EFAULT;
8900
goto exit;
8901
}
8902
#endif
8903
if (rtw_BT_efuse_map_read(padapter, addr, cnts, data) == _FAIL) {
8904
RTW_INFO("%s: rtw_BT_efuse_map_read error!!\n", __FUNCTION__);
8905
err = -EFAULT;
8906
goto exit;
8907
}
8908
8909
*extra = 0;
8910
pextra = extra;
8911
/* RTW_INFO("%s: bt efuse data={", __FUNCTION__); */
8912
for (i = 0; i < cnts; i++) {
8913
/* RTW_INFO("0x%02x ", data[i]); */
8914
pextra += sprintf(pextra, " 0x%02X ", data[i]);
8915
}
8916
/* RTW_INFO("}\n"); */
8917
RTW_INFO(FUNC_ADPT_FMT ": BT MAC=[%s]\n", FUNC_ADPT_ARG(padapter), extra);
8918
} else if (strcmp(tmp[0], "btffake") == 0) {
8919
/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8920
sprintf(extra, "\n");
8921
for (i = 0; i < 512; i += 16) {
8922
/* RTW_INFO("0x%03x\t", i); */
8923
pextra = extra + strlen(extra);
8924
pextra += sprintf(pextra, "0x%03x\t", i);
8925
for (j = 0; j < 8; j++) {
8926
/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
8927
pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
8928
}
8929
/* RTW_INFO("\t"); */
8930
pextra += sprintf(pextra, "\t");
8931
for (; j < 16; j++) {
8932
/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
8933
pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
8934
}
8935
/* RTW_INFO("\n"); */
8936
pextra += sprintf(pextra, "\n");
8937
}
8938
/* RTW_INFO("\n"); */
8939
} else if (strcmp(tmp[0], "btbfake") == 0) {
8940
/* RTW_INFO("OFFSET\tVALUE(hex)\n"); */
8941
sprintf(extra, "\n");
8942
for (i = 512; i < 1024; i += 16) {
8943
/* RTW_INFO("0x%03x\t", i); */
8944
pextra = extra + strlen(extra);
8945
pextra += sprintf(pextra, "0x%03x\t", i);
8946
for (j = 0; j < 8; j++) {
8947
/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
8948
pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
8949
}
8950
/* RTW_INFO("\t"); */
8951
pextra += sprintf(pextra, "\t");
8952
for (; j < 16; j++) {
8953
/* RTW_INFO("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]); */
8954
pextra += sprintf(pextra, "%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i+j]);
8955
}
8956
/* RTW_INFO("\n"); */
8957
pextra += sprintf(pextra, "\n");
8958
}
8959
/* RTW_INFO("\n"); */
8960
} else if (strcmp(tmp[0], "wlrfkmap") == 0) {
8961
static u8 fk_order = 0;
8962
u8 *efuse;
8963
u32 shift, cnt;
8964
u32 blksz = 0x200; /* The size of one time show, default 512 */
8965
8966
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&mapLen, _FALSE);
8967
efuse = pEfuseHal->fakeEfuseModifiedMap;
8968
8969
shift = blksz * fk_order;
8970
efuse += shift;
8971
cnt = mapLen - shift;
8972
if (cnt > blksz) {
8973
cnt = blksz;
8974
fk_order++;
8975
} else
8976
fk_order = 0;
8977
8978
sprintf(extra, "\n");
8979
for (i = 0; i < cnt; i += 16) {
8980
pextra = extra + strlen(extra);
8981
pextra += sprintf(pextra, "0x%02x\t", shift + i);
8982
for (j = 0; j < 8; j++)
8983
pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8984
pextra += sprintf(pextra, "\t");
8985
for (; j < 16; j++)
8986
pextra += sprintf(pextra, "%02X ", efuse[i + j]);
8987
pextra += sprintf(pextra, "\n");
8988
}
8989
if ((shift + cnt) < mapLen)
8990
pextra += sprintf(pextra, "\t...more\n");
8991
8992
} else if (strcmp(tmp[0], "wlrfkrmap") == 0) {
8993
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
8994
RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
8995
err = -EINVAL;
8996
goto exit;
8997
}
8998
/* rmap addr cnts */
8999
addr = simple_strtoul(tmp[1], &ptmp, 16);
9000
RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9001
9002
cnts = simple_strtoul(tmp[2], &ptmp, 10);
9003
if (cnts == 0) {
9004
RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9005
err = -EINVAL;
9006
goto exit;
9007
}
9008
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9009
9010
/* RTW_INFO("%s: data={", __FUNCTION__); */
9011
*extra = 0;
9012
pextra = extra;
9013
for (i = 0; i < cnts; i++) {
9014
RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9015
pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeEfuseModifiedMap[addr+i]);
9016
}
9017
} else if (strcmp(tmp[0], "btrfkrmap") == 0) {
9018
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9019
RTW_INFO("%s: rmap Fail!! Parameters error!\n", __FUNCTION__);
9020
err = -EINVAL;
9021
goto exit;
9022
}
9023
/* rmap addr cnts */
9024
addr = simple_strtoul(tmp[1], &ptmp, 16);
9025
RTW_INFO("%s: addr=%x\n", __FUNCTION__, addr);
9026
9027
cnts = simple_strtoul(tmp[2], &ptmp, 10);
9028
if (cnts == 0) {
9029
RTW_INFO("%s: rmap Fail!! cnts error!\n", __FUNCTION__);
9030
err = -EINVAL;
9031
goto exit;
9032
}
9033
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9034
9035
/* RTW_INFO("%s: data={", __FUNCTION__); */
9036
*extra = 0;
9037
pextra = extra;
9038
for (i = 0; i < cnts; i++) {
9039
RTW_INFO("wlrfkrmap = 0x%02x\n", pEfuseHal->fakeBTEfuseModifiedMap[addr + i]);
9040
pextra += sprintf(pextra, "0x%02X ", pEfuseHal->fakeBTEfuseModifiedMap[addr+i]);
9041
}
9042
} else if (strcmp(tmp[0], "mask") == 0) {
9043
*extra = 0;
9044
mask_len = sizeof(u8) * rtw_get_efuse_mask_arraylen(padapter);
9045
rtw_efuse_mask_array(padapter, mask_buf);
9046
9047
if (padapter->registrypriv.bFileMaskEfuse == _TRUE)
9048
_rtw_memcpy(mask_buf, maskfileBuffer, mask_len);
9049
9050
sprintf(extra, "\n");
9051
pextra = extra + strlen(extra);
9052
for (i = 0; i < mask_len; i++)
9053
pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);
9054
9055
} else if (strcmp(tmp[0], "btmask") == 0) {
9056
*extra = 0;
9057
mask_len = sizeof(u8) * rtw_get_bt_efuse_mask_arraylen(padapter);
9058
rtw_bt_efuse_mask_array(padapter, mask_buf);
9059
9060
if (padapter->registrypriv.bBTFileMaskEfuse == _TRUE)
9061
_rtw_memcpy(mask_buf, btmaskfileBuffer, mask_len);
9062
9063
sprintf(extra, "\n");
9064
pextra = extra + strlen(extra);
9065
for (i = 0; i < mask_len; i++)
9066
pextra += sprintf(pextra, "0x%02X\n", mask_buf[i]);
9067
9068
} else
9069
sprintf(extra, "Command not found!");
9070
9071
exit:
9072
if (data)
9073
rtw_mfree(data, EFUSE_BT_MAX_MAP_LEN);
9074
if (rawdata)
9075
rtw_mfree(rawdata, EFUSE_BT_MAX_MAP_LEN);
9076
if (!err)
9077
wrqu->length = strlen(extra);
9078
9079
if (padapter->registrypriv.mp_mode == 0) {
9080
#ifdef CONFIG_IPS
9081
rtw_pm_set_ips(padapter, ips_mode);
9082
#endif /* CONFIG_IPS */
9083
9084
#ifdef CONFIG_LPS
9085
rtw_pm_set_lps(padapter, lps_mode);
9086
#endif /* CONFIG_LPS */
9087
}
9088
9089
#ifdef CONFIG_IOL
9090
padapter->registrypriv.fw_iol = org_fw_iol;/* 0:Disable, 1:enable, 2:by usb speed */
9091
#endif
9092
return err;
9093
}
9094
9095
9096
#ifdef CONFIG_MP_INCLUDED
9097
static int rtw_mp_efuse_set(struct net_device *dev,
9098
struct iw_request_info *info,
9099
union iwreq_data *wdata, char *extra)
9100
{
9101
struct iw_point *wrqu;
9102
PADAPTER padapter;
9103
struct pwrctrl_priv *pwrctrlpriv ;
9104
PHAL_DATA_TYPE pHalData;
9105
PEFUSE_HAL pEfuseHal;
9106
struct hal_ops *pHalFunc;
9107
struct mp_priv *pmp_priv;
9108
9109
u8 ips_mode = IPS_NUM; /* init invalid value */
9110
u8 lps_mode = PS_MODE_NUM; /* init invalid value */
9111
u32 i = 0, j = 0, jj, kk;
9112
u8 *setdata = NULL;
9113
u8 *ShadowMapBT = NULL;
9114
u8 *ShadowMapWiFi = NULL;
9115
u8 *setrawdata = NULL;
9116
char *pch, *ptmp, *token, *tmp[3] = {0x00, 0x00, 0x00};
9117
u16 addr = 0xFF, cnts = 0, BTStatus = 0 , max_available_len = 0;
9118
u16 wifimaplen;
9119
int err;
9120
boolean bcmpchk = _TRUE;
9121
9122
9123
wrqu = (struct iw_point *)wdata;
9124
padapter = rtw_netdev_priv(dev);
9125
pwrctrlpriv = adapter_to_pwrctl(padapter);
9126
pHalData = GET_HAL_DATA(padapter);
9127
pEfuseHal = &pHalData->EfuseHal;
9128
pHalFunc = &padapter->hal_func;
9129
pmp_priv = &padapter->mppriv;
9130
9131
err = 0;
9132
9133
if (copy_from_user(extra, wrqu->pointer, wrqu->length))
9134
return -EFAULT;
9135
9136
*(extra + wrqu->length) = '\0';
9137
9138
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN , (void *)&wifimaplen, _FALSE);
9139
9140
setdata = rtw_zmalloc(1024);
9141
if (setdata == NULL) {
9142
err = -ENOMEM;
9143
goto exit;
9144
}
9145
ShadowMapBT = rtw_malloc(EFUSE_BT_MAX_MAP_LEN);
9146
if (ShadowMapBT == NULL) {
9147
err = -ENOMEM;
9148
goto exit;
9149
}
9150
ShadowMapWiFi = rtw_malloc(wifimaplen);
9151
if (ShadowMapWiFi == NULL) {
9152
err = -ENOMEM;
9153
goto exit;
9154
}
9155
setrawdata = rtw_malloc(EFUSE_MAX_SIZE);
9156
if (setrawdata == NULL) {
9157
err = -ENOMEM;
9158
goto exit;
9159
}
9160
9161
#ifdef CONFIG_LPS
9162
lps_mode = pwrctrlpriv->power_mgnt;/* keep org value */
9163
rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
9164
#endif
9165
9166
#ifdef CONFIG_IPS
9167
ips_mode = pwrctrlpriv->ips_mode;/* keep org value */
9168
rtw_pm_set_ips(padapter, IPS_NONE);
9169
#endif
9170
9171
pch = extra;
9172
RTW_INFO("%s: in=%s\n", __FUNCTION__, extra);
9173
9174
i = 0;
9175
while ((token = strsep(&pch, ",")) != NULL) {
9176
if (i > 2)
9177
break;
9178
tmp[i] = token;
9179
i++;
9180
}
9181
9182
/* tmp[0],[1],[2] */
9183
/* wmap,addr,00e04c871200 */
9184
if (strcmp(tmp[0], "wmap") == 0) {
9185
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9186
err = -EINVAL;
9187
goto exit;
9188
}
9189
9190
#ifndef RTW_HALMAC
9191
/* unknown bug workaround, need to fix later */
9192
addr = 0x1ff;
9193
rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9194
rtw_msleep_os(10);
9195
rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9196
rtw_msleep_os(10);
9197
rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9198
rtw_msleep_os(10);
9199
rtw_read8(padapter, EFUSE_CTRL);
9200
#endif /* RTW_HALMAC */
9201
9202
addr = simple_strtoul(tmp[1], &ptmp, 16);
9203
addr &= 0xFFF;
9204
9205
cnts = strlen(tmp[2]);
9206
if (cnts % 2) {
9207
err = -EINVAL;
9208
goto exit;
9209
}
9210
cnts /= 2;
9211
if (cnts == 0) {
9212
err = -EINVAL;
9213
goto exit;
9214
}
9215
9216
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9217
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9218
RTW_INFO("%s: map data=%s\n", __FUNCTION__, tmp[2]);
9219
9220
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9221
setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9222
9223
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9224
9225
if ((addr + cnts) > max_available_len) {
9226
RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9227
err = -EFAULT;
9228
goto exit;
9229
}
9230
9231
if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9232
RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9233
err = -EFAULT;
9234
goto exit;
9235
}
9236
*extra = 0;
9237
RTW_INFO("%s: after rtw_efuse_map_write to _rtw_memcmp\n", __func__);
9238
if (rtw_efuse_mask_map_read(padapter, addr, cnts, ShadowMapWiFi) == _SUCCESS) {
9239
if (_rtw_memcmp((void *)ShadowMapWiFi , (void *)setdata, cnts)) {
9240
RTW_INFO("%s: WiFi write map afterf compare success\n", __FUNCTION__);
9241
sprintf(extra, "WiFi write map compare OK\n");
9242
err = 0;
9243
goto exit;
9244
} else {
9245
sprintf(extra, "WiFi write map compare FAIL\n");
9246
RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9247
err = 0;
9248
goto exit;
9249
}
9250
}
9251
} else if (strcmp(tmp[0], "wraw") == 0) {
9252
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9253
err = -EINVAL;
9254
goto exit;
9255
}
9256
9257
addr = simple_strtoul(tmp[1], &ptmp, 16);
9258
addr &= 0xFFF;
9259
9260
cnts = strlen(tmp[2]);
9261
if (cnts % 2) {
9262
err = -EINVAL;
9263
goto exit;
9264
}
9265
cnts /= 2;
9266
if (cnts == 0) {
9267
err = -EINVAL;
9268
goto exit;
9269
}
9270
9271
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9272
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9273
RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9274
9275
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9276
setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9277
9278
if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9279
RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9280
err = -EFAULT;
9281
goto exit;
9282
}
9283
} else if (strcmp(tmp[0], "btwraw") == 0) {
9284
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9285
err = -EINVAL;
9286
goto exit;
9287
}
9288
9289
addr = simple_strtoul(tmp[1], &ptmp, 16);
9290
addr &= 0xFFF;
9291
9292
cnts = strlen(tmp[2]);
9293
if (cnts % 2) {
9294
err = -EINVAL;
9295
goto exit;
9296
}
9297
cnts /= 2;
9298
if (cnts == 0) {
9299
err = -EINVAL;
9300
goto exit;
9301
}
9302
9303
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9304
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9305
RTW_INFO("%s: raw data=%s\n", __FUNCTION__, tmp[2]);
9306
9307
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9308
setrawdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9309
#ifdef RTW_HALMAC
9310
if (rtw_efuse_bt_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9311
RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9312
err = -EFAULT;
9313
goto exit;
9314
}
9315
#else
9316
rtw_write8(padapter, 0x35, 1); /* switch bank 1 (BT)*/
9317
if (rtw_efuse_access(padapter, _TRUE, addr, cnts, setrawdata) == _FAIL) {
9318
RTW_INFO("%s: rtw_efuse_access error!!\n", __FUNCTION__);
9319
rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9320
err = -EFAULT;
9321
goto exit;
9322
}
9323
rtw_write8(padapter, 0x35, 0); /* switch bank 0 (WiFi)*/
9324
#endif
9325
} else if (strcmp(tmp[0], "mac") == 0) {
9326
if (tmp[1] == NULL) {
9327
err = -EINVAL;
9328
goto exit;
9329
}
9330
9331
/* mac,00e04c871200 */
9332
9333
if (hal_efuse_macaddr_offset(padapter) == -1) {
9334
err = -EFAULT;
9335
goto exit;
9336
}
9337
9338
addr = hal_efuse_macaddr_offset(padapter);
9339
cnts = strlen(tmp[1]);
9340
if (cnts % 2) {
9341
err = -EINVAL;
9342
goto exit;
9343
}
9344
cnts /= 2;
9345
if (cnts == 0) {
9346
err = -EINVAL;
9347
goto exit;
9348
}
9349
if (cnts > 6) {
9350
RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9351
err = -EFAULT;
9352
goto exit;
9353
}
9354
9355
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9356
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9357
RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9358
9359
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9360
setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9361
9362
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9363
9364
if ((addr + cnts) > max_available_len) {
9365
RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9366
err = -EFAULT;
9367
goto exit;
9368
}
9369
9370
if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9371
RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9372
err = -EFAULT;
9373
goto exit;
9374
}
9375
} else if (strcmp(tmp[0], "vidpid") == 0) {
9376
if (tmp[1] == NULL) {
9377
err = -EINVAL;
9378
goto exit;
9379
}
9380
9381
/* pidvid,da0b7881 */
9382
#ifdef CONFIG_RTL8188E
9383
#ifdef CONFIG_USB_HCI
9384
addr = EEPROM_VID_88EU;
9385
#endif
9386
#ifdef CONFIG_PCI_HCI
9387
addr = EEPROM_VID_88EE;
9388
#endif
9389
#endif /* CONFIG_RTL8188E */
9390
9391
#ifdef CONFIG_RTL8192E
9392
#ifdef CONFIG_USB_HCI
9393
addr = EEPROM_VID_8192EU;
9394
#endif
9395
#ifdef CONFIG_PCI_HCI
9396
addr = EEPROM_VID_8192EE;
9397
#endif
9398
#endif /* CONFIG_RTL8188E */
9399
9400
#ifdef CONFIG_RTL8723B
9401
addr = EEPROM_VID_8723BU;
9402
#endif
9403
9404
#ifdef CONFIG_RTL8188F
9405
addr = EEPROM_VID_8188FU;
9406
#endif
9407
9408
#ifdef CONFIG_RTL8188GTV
9409
addr = EEPROM_VID_8188GTVU;
9410
#endif
9411
9412
#ifdef CONFIG_RTL8703B
9413
#ifdef CONFIG_USB_HCI
9414
addr = EEPROM_VID_8703BU;
9415
#endif /* CONFIG_USB_HCI */
9416
#endif /* CONFIG_RTL8703B */
9417
9418
#ifdef CONFIG_RTL8723D
9419
#ifdef CONFIG_USB_HCI
9420
addr = EEPROM_VID_8723DU;
9421
#endif /* CONFIG_USB_HCI */
9422
#endif /* CONFIG_RTL8723D */
9423
9424
cnts = strlen(tmp[1]);
9425
if (cnts % 2) {
9426
err = -EINVAL;
9427
goto exit;
9428
}
9429
cnts /= 2;
9430
if (cnts == 0) {
9431
err = -EINVAL;
9432
goto exit;
9433
}
9434
9435
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9436
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9437
RTW_INFO("%s: VID/PID=%s\n", __FUNCTION__, tmp[1]);
9438
9439
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9440
setdata[jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9441
9442
EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9443
if ((addr + cnts) > max_available_len) {
9444
RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9445
err = -EFAULT;
9446
goto exit;
9447
}
9448
9449
if (rtw_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9450
RTW_INFO("%s: rtw_efuse_map_write error!!\n", __FUNCTION__);
9451
err = -EFAULT;
9452
goto exit;
9453
}
9454
} else if (strcmp(tmp[0], "wldumpfake") == 0) {
9455
if (wifimaplen > EFUSE_MAX_MAP_LEN)
9456
cnts = EFUSE_MAX_MAP_LEN;
9457
else
9458
cnts = wifimaplen;
9459
if (rtw_efuse_mask_map_read(padapter, 0, cnts, pEfuseHal->fakeEfuseModifiedMap) == _SUCCESS)
9460
RTW_INFO("%s: WiFi hw efuse dump to Fake map success\n", __func__);
9461
else {
9462
RTW_INFO("%s: WiFi hw efuse dump to Fake map Fail\n", __func__);
9463
err = -EFAULT;
9464
}
9465
} else if (strcmp(tmp[0], "btwmap") == 0) {
9466
rtw_write8(padapter, 0xa3, 0x05); /* For 8723AB ,8821S ? */
9467
BTStatus = rtw_read8(padapter, 0xa0);
9468
RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9469
if (BTStatus != 0x04) {
9470
sprintf(extra, "BT Status not Active ,can't do Write\n");
9471
goto exit;
9472
}
9473
9474
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9475
err = -EINVAL;
9476
goto exit;
9477
}
9478
9479
#ifndef RTW_HALMAC
9480
BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9481
addr = 0x1ff;
9482
rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9483
rtw_msleep_os(10);
9484
rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9485
rtw_msleep_os(10);
9486
rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9487
rtw_msleep_os(10);
9488
rtw_read8(padapter, EFUSE_CTRL);
9489
BTEfuse_PowerSwitch(padapter, 1, _FALSE);
9490
#endif /* RTW_HALMAC */
9491
9492
addr = simple_strtoul(tmp[1], &ptmp, 16);
9493
addr &= 0xFFF;
9494
9495
cnts = strlen(tmp[2]);
9496
if (cnts % 2) {
9497
err = -EINVAL;
9498
goto exit;
9499
}
9500
cnts /= 2;
9501
if (cnts == 0) {
9502
err = -EINVAL;
9503
goto exit;
9504
}
9505
9506
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9507
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9508
RTW_INFO("%s: BT data=%s\n", __FUNCTION__, tmp[2]);
9509
9510
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9511
setdata[jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9512
#ifndef RTW_HALMAC
9513
EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_EFUSE_MAP_LEN, (void *)&max_available_len, _FALSE);
9514
if ((addr + cnts) > max_available_len) {
9515
RTW_INFO("%s: addr(0x%X)+cnts(%d) parameter error!\n", __FUNCTION__, addr, cnts);
9516
err = -EFAULT;
9517
goto exit;
9518
}
9519
#endif
9520
if (rtw_BT_efuse_map_write(padapter, addr, cnts, setdata) == _FAIL) {
9521
RTW_INFO("%s: rtw_BT_efuse_map_write error!!\n", __FUNCTION__);
9522
err = -EFAULT;
9523
goto exit;
9524
}
9525
*extra = 0;
9526
RTW_INFO("%s: after rtw_BT_efuse_map_write to _rtw_memcmp\n", __FUNCTION__);
9527
if ((rtw_BT_efuse_map_read(padapter, addr, cnts, ShadowMapBT) == _SUCCESS)) {
9528
if (_rtw_memcmp((void *)ShadowMapBT , (void *)setdata, cnts)) {
9529
RTW_INFO("%s: BT write map compare OK BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9530
sprintf(extra, "BT write map compare OK");
9531
err = 0;
9532
goto exit;
9533
} else {
9534
sprintf(extra, "BT write map compare FAIL");
9535
RTW_INFO("%s: BT write map compare FAIL BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9536
err = 0;
9537
goto exit;
9538
}
9539
}
9540
} else if (strcmp(tmp[0], "btwfake") == 0) {
9541
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9542
err = -EINVAL;
9543
goto exit;
9544
}
9545
if (pmp_priv->bprocess_mp_mode != _TRUE) {
9546
RTW_INFO("%s: btwfake not to be exec, please first to mp_start\n", __FUNCTION__);
9547
sprintf(extra, "Error, btwfake cant to be exec, please first to mp_start !!!!\n");
9548
err = 0;
9549
goto exit;
9550
}
9551
addr = simple_strtoul(tmp[1], &ptmp, 16);
9552
addr &= 0xFFF;
9553
9554
cnts = strlen(tmp[2]);
9555
if (cnts % 2) {
9556
err = -EINVAL;
9557
goto exit;
9558
}
9559
cnts /= 2;
9560
if (cnts == 0) {
9561
err = -EINVAL;
9562
goto exit;
9563
}
9564
9565
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9566
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9567
RTW_INFO("%s: BT tmp data=%s\n", __FUNCTION__, tmp[2]);
9568
9569
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9570
pEfuseHal->fakeBTEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9571
} else if (strcmp(tmp[0], "btdumpfake") == 0) {
9572
if (rtw_BT_efuse_map_read(padapter, 0, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _SUCCESS)
9573
RTW_INFO("%s: BT read all map success\n", __FUNCTION__);
9574
else {
9575
RTW_INFO("%s: BT read all map Fail!\n", __FUNCTION__);
9576
err = -EFAULT;
9577
}
9578
} else if (strcmp(tmp[0], "btfk2map") == 0) {
9579
9580
if (padapter->registrypriv.bBTFileMaskEfuse != _TRUE && pmp_priv->bloadBTefusemap == _TRUE) {
9581
RTW_INFO("%s: File BT eFuse mask file not to be loaded\n", __FUNCTION__);
9582
sprintf(extra, "Not load BT eFuse mask file yet, Please advance to use [ efuse_bt_mask ], now remove the Adapter.!!!!\n");
9583
rtw_set_surprise_removed(padapter);
9584
err = 0;
9585
goto exit;
9586
}
9587
9588
rtw_write8(padapter, 0xa3, 0x05);
9589
BTStatus = rtw_read8(padapter, 0xa0);
9590
RTW_INFO("%s: btwmap before read 0xa0 BT Status =0x%x\n", __FUNCTION__, BTStatus);
9591
if (BTStatus != 0x04) {
9592
sprintf(extra, "BT Status not Active Write FAIL\n");
9593
goto exit;
9594
}
9595
if (pmp_priv->bprocess_mp_mode != _TRUE) {
9596
RTW_INFO("%s: btfk2map not to be exec, please first to mp_start\n", __FUNCTION__);
9597
sprintf(extra, "Error, btfk2map cant to be exec, please first to mp_start !!!!\n");
9598
err = 0;
9599
goto exit;
9600
}
9601
#ifndef RTW_HALMAC
9602
BTEfuse_PowerSwitch(padapter, 1, _TRUE);
9603
addr = 0x1ff;
9604
rtw_write8(padapter, EFUSE_CTRL + 1, (addr & 0xff));
9605
rtw_msleep_os(10);
9606
rtw_write8(padapter, EFUSE_CTRL + 2, ((addr >> 8) & 0x03));
9607
rtw_msleep_os(10);
9608
rtw_write8(padapter, EFUSE_CTRL + 3, 0x72);
9609
rtw_msleep_os(10);
9610
rtw_read8(padapter, EFUSE_CTRL);
9611
BTEfuse_PowerSwitch(padapter, 1, _FALSE);
9612
#endif /* RTW_HALMAC */
9613
_rtw_memcpy(pEfuseHal->BTEfuseModifiedMap, pEfuseHal->fakeBTEfuseModifiedMap, EFUSE_BT_MAX_MAP_LEN);
9614
9615
if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL) {
9616
RTW_INFO("%s: rtw_BT_efuse_map_write error!\n", __FUNCTION__);
9617
err = -EFAULT;
9618
goto exit;
9619
}
9620
9621
RTW_INFO("pEfuseHal->fakeBTEfuseModifiedMap OFFSET\tVALUE(hex)\n");
9622
for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
9623
printk("0x%02x\t", i);
9624
for (j = 0; j < 8; j++)
9625
printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9626
printk("\t");
9627
9628
for (; j < 16; j++)
9629
printk("%02X ", pEfuseHal->fakeBTEfuseModifiedMap[i + j]);
9630
printk("\n");
9631
}
9632
printk("\n");
9633
#if 1
9634
err = -EFAULT;
9635
RTW_INFO("%s: rtw_BT_efuse_map_read _rtw_memcmp\n", __FUNCTION__);
9636
if ((rtw_BT_efuse_map_read(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS)) {
9637
if (_rtw_memcmp((void *)pEfuseHal->fakeBTEfuseModifiedMap, (void *)pEfuseHal->fakeBTEfuseInitMap, EFUSE_BT_MAX_MAP_LEN)) {
9638
sprintf(extra, "BT write map compare OK");
9639
RTW_INFO("%s: BT write map afterf compare success BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9640
err = 0;
9641
goto exit;
9642
} else {
9643
sprintf(extra, "BT write map compare FAIL");
9644
if (rtw_BT_efuse_map_write(padapter, 0x00, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseModifiedMap) == _FAIL)
9645
RTW_INFO("%s: rtw_BT_efuse_map_write compare error,retry = %d!\n", __FUNCTION__, i);
9646
9647
if (rtw_BT_efuse_map_read(padapter, EFUSE_BT, EFUSE_BT_MAX_MAP_LEN, pEfuseHal->fakeBTEfuseInitMap) == _SUCCESS) {
9648
RTW_INFO("pEfuseHal->fakeBTEfuseInitMap OFFSET\tVALUE(hex)\n");
9649
9650
for (i = 0; i < EFUSE_BT_MAX_MAP_LEN; i += 16) {
9651
printk("0x%02x\t", i);
9652
for (j = 0; j < 8; j++)
9653
printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
9654
printk("\t");
9655
for (; j < 16; j++)
9656
printk("%02X ", pEfuseHal->fakeBTEfuseInitMap[i + j]);
9657
printk("\n");
9658
}
9659
printk("\n");
9660
}
9661
RTW_INFO("%s: BT write map afterf compare not match to write efuse try write Map again , BTStatus=0x%x\n", __FUNCTION__, BTStatus);
9662
goto exit;
9663
}
9664
}
9665
#endif
9666
9667
} else if (strcmp(tmp[0], "wlfk2map") == 0) {
9668
*extra = 0;
9669
9670
if (padapter->registrypriv.bFileMaskEfuse != _TRUE && pmp_priv->bloadefusemap == _TRUE) {
9671
RTW_INFO("%s: File eFuse mask file not to be loaded\n", __FUNCTION__);
9672
sprintf(extra, "Not load eFuse mask file yet, Please use the efuse_mask CMD, now remove the interface !!!!\n");
9673
rtw_set_surprise_removed(padapter);
9674
err = 0;
9675
goto exit;
9676
}
9677
9678
if (pmp_priv->bprocess_mp_mode != _TRUE) {
9679
RTW_INFO("%s: wlfk2map not to be exec, please first to mp_start\n", __FUNCTION__);
9680
sprintf(extra, "Error, wlfk2map cant to be exec, please first to mp_start !!!!\n");
9681
err = 0;
9682
goto exit;
9683
}
9684
if (wifimaplen > EFUSE_MAX_MAP_LEN)
9685
cnts = EFUSE_MAX_MAP_LEN;
9686
else
9687
cnts = wifimaplen;
9688
if (rtw_efuse_map_write(padapter, 0x00, cnts, pEfuseHal->fakeEfuseModifiedMap) == _FAIL) {
9689
RTW_INFO("%s: rtw_efuse_map_write fakeEfuseModifiedMap error!\n", __FUNCTION__);
9690
err = -EFAULT;
9691
goto exit;
9692
}
9693
9694
if (rtw_efuse_mask_map_read(padapter, 0x00, wifimaplen, ShadowMapWiFi) == _SUCCESS) {
9695
addr = 0x00;
9696
err = _TRUE;
9697
9698
for (i = 0; i < cnts; i++) {
9699
if (padapter->registrypriv.boffefusemask == 0) {
9700
if (padapter->registrypriv.bFileMaskEfuse == _TRUE) {
9701
if (rtw_file_efuse_IsMasked(padapter, addr + i, maskfileBuffer) == _TRUE) /*use file efuse mask. */
9702
bcmpchk = _FALSE;
9703
} else {
9704
if (efuse_IsMasked(padapter, addr + i) == _TRUE)
9705
bcmpchk = _FALSE;
9706
}
9707
}
9708
9709
if (bcmpchk == _TRUE) {
9710
RTW_INFO("compare readMapWiFi[0x%02x] = %x, ModifiedMap = %x\n", addr + i, ShadowMapWiFi[ addr + i], pEfuseHal->fakeEfuseModifiedMap[addr + i]);
9711
if (_rtw_memcmp((void *) &ShadowMapWiFi[addr + i], (void *)&pEfuseHal->fakeEfuseModifiedMap[addr + i], 1) == _FALSE){
9712
err = _FALSE;
9713
break;
9714
}
9715
}
9716
bcmpchk = _TRUE;
9717
}
9718
}
9719
9720
if (err) {
9721
RTW_INFO("%s: WiFi write map afterf compare OK\n", __FUNCTION__);
9722
sprintf(extra, "WiFi write map compare OK\n");
9723
err = 0;
9724
goto exit;
9725
} else {
9726
sprintf(extra, "WiFi write map compare FAIL\n");
9727
RTW_INFO("%s: WiFi write map compare Fail\n", __FUNCTION__);
9728
err = 0;
9729
goto exit;
9730
}
9731
} else if (strcmp(tmp[0], "wlwfake") == 0) {
9732
if ((tmp[1] == NULL) || (tmp[2] == NULL)) {
9733
err = -EINVAL;
9734
goto exit;
9735
}
9736
if (pmp_priv->bprocess_mp_mode != _TRUE) {
9737
RTW_INFO("%s: wlwfake not to be exec, please first to mp_start\n", __FUNCTION__);
9738
sprintf(extra, "Error, wlwfake cant to be exec, please first to mp_start !!!!\n");
9739
err = 0;
9740
goto exit;
9741
}
9742
addr = simple_strtoul(tmp[1], &ptmp, 16);
9743
addr &= 0xFFF;
9744
9745
cnts = strlen(tmp[2]);
9746
if (cnts % 2) {
9747
err = -EINVAL;
9748
goto exit;
9749
}
9750
cnts /= 2;
9751
if (cnts == 0) {
9752
err = -EINVAL;
9753
goto exit;
9754
}
9755
9756
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9757
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9758
RTW_INFO("%s: map tmp data=%s\n", __FUNCTION__, tmp[2]);
9759
9760
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9761
pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[2][kk], tmp[2][kk + 1]);
9762
_rtw_memset(extra, '\0', strlen(extra));
9763
sprintf(extra, "wlwfake OK\n");
9764
9765
}
9766
else if (strcmp(tmp[0], "wfakemac") == 0) {
9767
if (tmp[1] == NULL) {
9768
err = -EINVAL;
9769
goto exit;
9770
}
9771
if (pmp_priv->bprocess_mp_mode != _TRUE) {
9772
RTW_INFO("%s: wfakemac not to be exec, please first to mp_start\n", __FUNCTION__);
9773
sprintf(extra, "Error, wfakemac cant to be exec, please first to mp_start !!!!\n");
9774
err = 0;
9775
goto exit;
9776
}
9777
/* wfakemac,00e04c871200 */
9778
if (hal_efuse_macaddr_offset(padapter) == -1) {
9779
err = -EFAULT;
9780
goto exit;
9781
}
9782
9783
addr = hal_efuse_macaddr_offset(padapter);
9784
cnts = strlen(tmp[1]);
9785
if (cnts % 2) {
9786
err = -EINVAL;
9787
goto exit;
9788
}
9789
cnts /= 2;
9790
if (cnts == 0) {
9791
err = -EINVAL;
9792
goto exit;
9793
}
9794
if (cnts > 6) {
9795
RTW_INFO("%s: error data for mac addr=\"%s\"\n", __FUNCTION__, tmp[1]);
9796
err = -EFAULT;
9797
goto exit;
9798
}
9799
9800
RTW_INFO("%s: addr=0x%X\n", __FUNCTION__, addr);
9801
RTW_INFO("%s: cnts=%d\n", __FUNCTION__, cnts);
9802
RTW_INFO("%s: MAC address=%s\n", __FUNCTION__, tmp[1]);
9803
9804
for (jj = 0, kk = 0; jj < cnts; jj++, kk += 2)
9805
pEfuseHal->fakeEfuseModifiedMap[addr + jj] = key_2char2num(tmp[1][kk], tmp[1][kk + 1]);
9806
9807
_rtw_memset(extra, '\0', strlen(extra));
9808
sprintf(extra, "write mac addr to fake map OK\n");
9809
} else if(strcmp(tmp[0], "update") == 0) {
9810
RTW_INFO("To Use new eFuse map\n");
9811
/*step read efuse/eeprom data and get mac_addr*/
9812
rtw_hal_read_chip_info(padapter);
9813
/* set mac addr*/
9814
rtw_macaddr_cfg(adapter_mac_addr(padapter), get_hal_mac_addr(padapter));
9815
_rtw_memcpy(padapter->pnetdev->dev_addr, get_hal_mac_addr(padapter), ETH_ALEN); /* set mac addr to net_device */
9816
9817
#ifdef CONFIG_P2P
9818
rtw_init_wifidirect_addrs(padapter, adapter_mac_addr(padapter), adapter_mac_addr(padapter));
9819
#endif
9820
#ifdef CONFIG_MI_WITH_MBSSID_CAM
9821
rtw_hal_change_macaddr_mbid(padapter, adapter_mac_addr(padapter));
9822
#else
9823
rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR, adapter_mac_addr(padapter)); /* set mac addr to mac register */
9824
#endif
9825
/*pHalFunc->hal_deinit(padapter);*/
9826
if (pHalFunc->hal_init(padapter) == _FAIL) {
9827
err = -EINVAL;
9828
goto exit;
9829
}
9830
_rtw_memset(extra, '\0', strlen(extra));
9831
sprintf(extra, "eFuse Update OK\n");
9832
} else if (strcmp(tmp[0], "analyze") == 0) {
9833
9834
rtw_efuse_analyze(padapter, EFUSE_WIFI, 0);
9835
_rtw_memset(extra, '\0', strlen(extra));
9836
sprintf(extra, "eFuse Analyze OK,please to check kernel log\n");
9837
}
9838
exit:
9839
if (setdata)
9840
rtw_mfree(setdata, 1024);
9841
if (ShadowMapBT)
9842
rtw_mfree(ShadowMapBT, EFUSE_BT_MAX_MAP_LEN);
9843
if (ShadowMapWiFi)
9844
rtw_mfree(ShadowMapWiFi, wifimaplen);
9845
if (setrawdata)
9846
rtw_mfree(setrawdata, EFUSE_MAX_SIZE);
9847
9848
wrqu->length = strlen(extra);
9849
9850
if (padapter->registrypriv.mp_mode == 0) {
9851
#ifdef CONFIG_IPS
9852
rtw_pm_set_ips(padapter, ips_mode);
9853
#endif /* CONFIG_IPS */
9854
9855
#ifdef CONFIG_LPS
9856
rtw_pm_set_lps(padapter, lps_mode);
9857
#endif /* CONFIG_LPS */
9858
}
9859
9860
return err;
9861
}
9862
9863
#ifdef CONFIG_RTW_CUSTOMER_STR
9864
static int rtw_mp_customer_str(
9865
struct net_device *dev,
9866
struct iw_request_info *info,
9867
union iwreq_data *wrqu, char *extra)
9868
{
9869
_adapter *adapter = rtw_netdev_priv(dev);
9870
u32 len;
9871
u8 *pbuf = NULL, *pch;
9872
char *ptmp;
9873
u8 param[RTW_CUSTOMER_STR_LEN];
9874
u8 count = 0;
9875
u8 tmp;
9876
u8 i;
9877
u32 pos;
9878
u8 ret;
9879
u8 read = 0;
9880
9881
if (adapter->registrypriv.mp_mode != 1
9882
|| !adapter->registrypriv.mp_customer_str)
9883
return -EFAULT;
9884
9885
len = wrqu->data.length + 1;
9886
9887
pbuf = (u8 *)rtw_zmalloc(len);
9888
if (pbuf == NULL) {
9889
RTW_WARN("%s: no memory!\n", __func__);
9890
return -ENOMEM;
9891
}
9892
9893
if (copy_from_user(pbuf, wrqu->data.pointer, wrqu->data.length)) {
9894
rtw_mfree(pbuf, len);
9895
RTW_WARN("%s: copy from user fail!\n", __func__);
9896
return -EFAULT;
9897
}
9898
RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
9899
9900
ptmp = (char *)pbuf;
9901
pch = strsep(&ptmp, ",");
9902
if ((pch == NULL) || (strlen(pch) == 0)) {
9903
rtw_mfree(pbuf, len);
9904
RTW_INFO("%s: parameter error(no cmd)!\n", __func__);
9905
return -EFAULT;
9906
}
9907
9908
_rtw_memset(param, 0xFF, RTW_CUSTOMER_STR_LEN);
9909
9910
if (strcmp(pch, "read") == 0) {
9911
read = 1;
9912
ret = rtw_hal_customer_str_read(adapter, param);
9913
9914
} else if (strcmp(pch, "write") == 0) {
9915
do {
9916
pch = strsep(&ptmp, ":");
9917
if ((pch == NULL) || (strlen(pch) == 0))
9918
break;
9919
if (strlen(pch) != 2
9920
|| IsHexDigit(*pch) == _FALSE
9921
|| IsHexDigit(*(pch + 1)) == _FALSE
9922
|| sscanf(pch, "%hhx", &tmp) != 1
9923
) {
9924
RTW_WARN("%s: invalid 8-bit hex!\n", __func__);
9925
rtw_mfree(pbuf, len);
9926
return -EFAULT;
9927
}
9928
9929
param[count++] = tmp;
9930
9931
} while (count < RTW_CUSTOMER_STR_LEN);
9932
9933
if (count == 0) {
9934
rtw_mfree(pbuf, len);
9935
RTW_WARN("%s: no input!\n", __func__);
9936
return -EFAULT;
9937
}
9938
ret = rtw_hal_customer_str_write(adapter, param);
9939
} else {
9940
rtw_mfree(pbuf, len);
9941
RTW_INFO("%s: parameter error(unknown cmd)!\n", __func__);
9942
return -EFAULT;
9943
}
9944
9945
pos = sprintf(extra, "%s: ", read ? "read" : "write");
9946
if (read == 0 || ret == _SUCCESS) {
9947
for (i = 0; i < RTW_CUSTOMER_STR_LEN; i++)
9948
pos += sprintf(extra + pos, "%02x:", param[i]);
9949
extra[pos] = 0;
9950
pos--;
9951
}
9952
pos += sprintf(extra + pos, " %s", ret == _SUCCESS ? "OK" : "FAIL");
9953
9954
wrqu->data.length = strlen(extra) + 1;
9955
9956
rtw_mfree(pbuf, len);
9957
return 0;
9958
}
9959
#endif /* CONFIG_RTW_CUSTOMER_STR */
9960
9961
static int rtw_priv_mp_set(struct net_device *dev,
9962
struct iw_request_info *info,
9963
union iwreq_data *wdata, char *extra)
9964
{
9965
9966
struct iw_point *wrqu = (struct iw_point *)wdata;
9967
u32 subcmd = wrqu->flags;
9968
PADAPTER padapter = rtw_netdev_priv(dev);
9969
int status = 0;
9970
9971
#ifdef CONFIG_CONCURRENT_MODE
9972
if (!is_primary_adapter(padapter)) {
9973
RTW_INFO("MP mode only primary Adapter support\n");
9974
return -EIO;
9975
}
9976
#endif
9977
9978
RTW_INFO("%s mutx in %d\n", __func__, subcmd);
9979
_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
9980
switch (subcmd) {
9981
case CTA_TEST:
9982
RTW_INFO("set CTA_TEST\n");
9983
status = rtw_cta_test_start(dev, info, wdata, extra);
9984
break;
9985
case MP_DISABLE_BT_COEXIST:
9986
RTW_INFO("set case MP_DISABLE_BT_COEXIST\n");
9987
status = rtw_mp_disable_bt_coexist(dev, info, wdata, extra);
9988
break;
9989
case MP_IQK:
9990
RTW_INFO("set MP_IQK\n");
9991
status = rtw_mp_iqk(dev, info, wrqu, extra);
9992
break;
9993
case MP_LCK:
9994
RTW_INFO("set MP_LCK\n");
9995
status = rtw_mp_lck(dev, info, wrqu, extra);
9996
break;
9997
9998
default:
9999
status = -EIO;
10000
}
10001
_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10002
RTW_INFO("%s mutx done %d\n", __func__, subcmd);
10003
10004
return status;
10005
}
10006
10007
static int rtw_priv_mp_get(struct net_device *dev,
10008
struct iw_request_info *info,
10009
union iwreq_data *wdata, char *extra)
10010
{
10011
10012
struct iw_point *wrqu = (struct iw_point *)wdata;
10013
u32 subcmd = wrqu->flags;
10014
PADAPTER padapter = rtw_netdev_priv(dev);
10015
int status = 0;
10016
10017
#ifdef CONFIG_CONCURRENT_MODE
10018
if (!is_primary_adapter(padapter)) {
10019
RTW_INFO("MP mode only primary Adapter support\n");
10020
return -EIO;
10021
}
10022
#endif
10023
10024
RTW_INFO("%s mutx in %d\n", __func__, subcmd);
10025
_enter_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10026
10027
switch (subcmd) {
10028
case MP_START:
10029
RTW_INFO("set case mp_start\n");
10030
status = rtw_mp_start(dev, info, wrqu, extra);
10031
break;
10032
case MP_STOP:
10033
RTW_INFO("set case mp_stop\n");
10034
status = rtw_mp_stop(dev, info, wrqu, extra);
10035
break;
10036
case MP_BANDWIDTH:
10037
RTW_INFO("set case mp_bandwidth\n");
10038
status = rtw_mp_bandwidth(dev, info, wrqu, extra);
10039
break;
10040
case MP_RESET_STATS:
10041
RTW_INFO("set case MP_RESET_STATS\n");
10042
status = rtw_mp_reset_stats(dev, info, wrqu, extra);
10043
break;
10044
case MP_SetRFPathSwh:
10045
RTW_INFO("set MP_SetRFPathSwitch\n");
10046
status = rtw_mp_SetRFPath(dev, info, wrqu, extra);
10047
break;
10048
case WRITE_REG:
10049
status = rtw_mp_write_reg(dev, info, wrqu, extra);
10050
break;
10051
case WRITE_RF:
10052
status = rtw_mp_write_rf(dev, info, wrqu, extra);
10053
break;
10054
case MP_PHYPARA:
10055
RTW_INFO("mp_get MP_PHYPARA\n");
10056
status = rtw_mp_phypara(dev, info, wrqu, extra);
10057
break;
10058
case MP_CHANNEL:
10059
RTW_INFO("set case mp_channel\n");
10060
status = rtw_mp_channel(dev , info, wrqu, extra);
10061
break;
10062
case MP_CHL_OFFSET:
10063
RTW_INFO("set case mp_ch_offset\n");
10064
status = rtw_mp_ch_offset(dev , info, wrqu, extra);
10065
break;
10066
case READ_REG:
10067
RTW_INFO("mp_get READ_REG\n");
10068
status = rtw_mp_read_reg(dev, info, wrqu, extra);
10069
break;
10070
case READ_RF:
10071
RTW_INFO("mp_get READ_RF\n");
10072
status = rtw_mp_read_rf(dev, info, wrqu, extra);
10073
break;
10074
case MP_RATE:
10075
RTW_INFO("set case mp_rate\n");
10076
status = rtw_mp_rate(dev, info, wrqu, extra);
10077
break;
10078
case MP_TXPOWER:
10079
RTW_INFO("set case MP_TXPOWER\n");
10080
status = rtw_mp_txpower(dev, info, wrqu, extra);
10081
break;
10082
case MP_ANT_TX:
10083
RTW_INFO("set case MP_ANT_TX\n");
10084
status = rtw_mp_ant_tx(dev, info, wrqu, extra);
10085
break;
10086
case MP_ANT_RX:
10087
RTW_INFO("set case MP_ANT_RX\n");
10088
status = rtw_mp_ant_rx(dev, info, wrqu, extra);
10089
break;
10090
case MP_QUERY:
10091
status = rtw_mp_trx_query(dev, info, wrqu, extra);
10092
break;
10093
case MP_CTX:
10094
RTW_INFO("set case MP_CTX\n");
10095
status = rtw_mp_ctx(dev, info, wrqu, extra);
10096
break;
10097
case MP_ARX:
10098
RTW_INFO("set case MP_ARX\n");
10099
status = rtw_mp_arx(dev, info, wrqu, extra);
10100
break;
10101
case MP_DUMP:
10102
RTW_INFO("set case MP_DUMP\n");
10103
status = rtw_mp_dump(dev, info, wrqu, extra);
10104
break;
10105
case MP_PSD:
10106
RTW_INFO("set case MP_PSD\n");
10107
status = rtw_mp_psd(dev, info, wrqu, extra);
10108
break;
10109
case MP_THER:
10110
RTW_INFO("set case MP_THER\n");
10111
status = rtw_mp_thermal(dev, info, wrqu, extra);
10112
break;
10113
case MP_PwrCtlDM:
10114
RTW_INFO("set MP_PwrCtlDM\n");
10115
status = rtw_mp_PwrCtlDM(dev, info, wrqu, extra);
10116
break;
10117
case MP_QueryDrvStats:
10118
RTW_INFO("mp_get MP_QueryDrvStats\n");
10119
status = rtw_mp_QueryDrv(dev, info, wdata, extra);
10120
break;
10121
case MP_PWRTRK:
10122
RTW_INFO("set case MP_PWRTRK\n");
10123
status = rtw_mp_pwrtrk(dev, info, wrqu, extra);
10124
break;
10125
#ifdef CONFIG_MP_INCLUDED
10126
case EFUSE_SET:
10127
RTW_INFO("set case efuse set\n");
10128
status = rtw_mp_efuse_set(dev, info, wdata, extra);
10129
break;
10130
#endif
10131
case EFUSE_GET:
10132
RTW_INFO("efuse get EFUSE_GET\n");
10133
status = rtw_mp_efuse_get(dev, info, wdata, extra);
10134
break;
10135
case MP_GET_TXPOWER_INX:
10136
RTW_INFO("mp_get MP_GET_TXPOWER_INX\n");
10137
status = rtw_mp_txpower_index(dev, info, wrqu, extra);
10138
break;
10139
case MP_GETVER:
10140
RTW_INFO("mp_get MP_GETVER\n");
10141
status = rtw_mp_getver(dev, info, wdata, extra);
10142
break;
10143
case MP_MON:
10144
RTW_INFO("mp_get MP_MON\n");
10145
status = rtw_mp_mon(dev, info, wdata, extra);
10146
break;
10147
case EFUSE_BT_MASK:
10148
RTW_INFO("mp_get EFUSE_BT_MASK\n");
10149
status = rtw_bt_efuse_mask_file(dev, info, wdata, extra);
10150
break;
10151
case EFUSE_MASK:
10152
RTW_INFO("mp_get EFUSE_MASK\n");
10153
status = rtw_efuse_mask_file(dev, info, wdata, extra);
10154
break;
10155
case EFUSE_FILE:
10156
RTW_INFO("mp_get EFUSE_FILE\n");
10157
status = rtw_efuse_file_map(dev, info, wdata, extra);
10158
break;
10159
case MP_TX:
10160
RTW_INFO("mp_get MP_TX\n");
10161
status = rtw_mp_tx(dev, info, wdata, extra);
10162
break;
10163
case MP_RX:
10164
RTW_INFO("mp_get MP_RX\n");
10165
status = rtw_mp_rx(dev, info, wdata, extra);
10166
break;
10167
case MP_HW_TX_MODE:
10168
RTW_INFO("mp_get MP_HW_TX_MODE\n");
10169
status = rtw_mp_hwtx(dev, info, wdata, extra);
10170
break;
10171
#ifdef CONFIG_RTW_CUSTOMER_STR
10172
case MP_CUSTOMER_STR:
10173
RTW_INFO("customer str\n");
10174
status = rtw_mp_customer_str(dev, info, wdata, extra);
10175
break;
10176
#endif
10177
case MP_PWRLMT:
10178
RTW_INFO("mp_get MP_SETPWRLMT\n");
10179
status = rtw_mp_pwrlmt(dev, info, wdata, extra);
10180
break;
10181
case MP_PWRBYRATE:
10182
RTW_INFO("mp_get MP_SETPWRBYRATE\n");
10183
status = rtw_mp_pwrbyrate(dev, info, wdata, extra);
10184
break;
10185
case BT_EFUSE_FILE:
10186
RTW_INFO("mp_get BT EFUSE_FILE\n");
10187
status = rtw_bt_efuse_file_map(dev, info, wdata, extra);
10188
break;
10189
case MP_SWRFPath:
10190
RTW_INFO("mp_get MP_SWRFPath\n");
10191
status = rtw_mp_switch_rf_path(dev, info, wrqu, extra);
10192
break;
10193
case MP_LINK:
10194
RTW_INFO("mp_get MP_LINK\n");
10195
status = rtw_mp_link(dev, info, wrqu, extra);
10196
break;
10197
case MP_DPK_TRK:
10198
RTW_INFO("mp_get MP_DPK_TRK\n");
10199
status = rtw_mp_dpk_track(dev, info, wdata, extra);
10200
break;
10201
case MP_DPK:
10202
RTW_INFO("set MP_DPK\n");
10203
status = rtw_mp_dpk(dev, info, wdata, extra);
10204
break;
10205
default:
10206
status = -EIO;
10207
}
10208
10209
_exit_critical_mutex(&(adapter_to_dvobj(padapter)->ioctrl_mutex), NULL);
10210
RTW_INFO("%s mutx done_%d\n", __func__, subcmd);
10211
10212
return status;
10213
}
10214
#endif /*#if defined(CONFIG_MP_INCLUDED)*/
10215
10216
10217
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
10218
#define DBG_MP_SDIO_INDIRECT_ACCESS 1
10219
static int rtw_mp_sd_iread(struct net_device *dev
10220
, struct iw_request_info *info
10221
, struct iw_point *wrqu
10222
, char *extra)
10223
{
10224
char input[16];
10225
u8 width;
10226
unsigned long addr;
10227
u32 ret = 0;
10228
PADAPTER padapter = rtw_netdev_priv(dev);
10229
10230
if (wrqu->length > 16) {
10231
RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10232
ret = -EINVAL;
10233
goto exit;
10234
}
10235
10236
if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10237
RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10238
ret = -EFAULT;
10239
goto exit;
10240
}
10241
10242
_rtw_memset(extra, 0, wrqu->length);
10243
10244
if (sscanf(input, "%hhu,%lx", &width, &addr) != 2) {
10245
RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10246
ret = -EINVAL;
10247
goto exit;
10248
}
10249
10250
if (addr > 0x3FFF) {
10251
RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10252
ret = -EINVAL;
10253
goto exit;
10254
}
10255
10256
if (DBG_MP_SDIO_INDIRECT_ACCESS)
10257
RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr);
10258
10259
switch (width) {
10260
case 1:
10261
sprintf(extra, "0x%02x", rtw_sd_iread8(padapter, addr));
10262
wrqu->length = strlen(extra);
10263
break;
10264
case 2:
10265
sprintf(extra, "0x%04x", rtw_sd_iread16(padapter, addr));
10266
wrqu->length = strlen(extra);
10267
break;
10268
case 4:
10269
sprintf(extra, "0x%08x", rtw_sd_iread32(padapter, addr));
10270
wrqu->length = strlen(extra);
10271
break;
10272
default:
10273
wrqu->length = 0;
10274
ret = -EINVAL;
10275
break;
10276
}
10277
10278
exit:
10279
return ret;
10280
}
10281
10282
static int rtw_mp_sd_iwrite(struct net_device *dev
10283
, struct iw_request_info *info
10284
, struct iw_point *wrqu
10285
, char *extra)
10286
{
10287
char width;
10288
unsigned long addr, data;
10289
int ret = 0;
10290
PADAPTER padapter = rtw_netdev_priv(dev);
10291
char input[32];
10292
10293
if (wrqu->length > 32) {
10294
RTW_INFO(FUNC_ADPT_FMT" wrqu->length:%d\n", FUNC_ADPT_ARG(padapter), wrqu->length);
10295
ret = -EINVAL;
10296
goto exit;
10297
}
10298
10299
if (copy_from_user(input, wrqu->pointer, wrqu->length)) {
10300
RTW_INFO(FUNC_ADPT_FMT" copy_from_user fail\n", FUNC_ADPT_ARG(padapter));
10301
ret = -EFAULT;
10302
goto exit;
10303
}
10304
10305
_rtw_memset(extra, 0, wrqu->length);
10306
10307
if (sscanf(input, "%hhu,%lx,%lx", &width, &addr, &data) != 3) {
10308
RTW_INFO(FUNC_ADPT_FMT" sscanf fail\n", FUNC_ADPT_ARG(padapter));
10309
ret = -EINVAL;
10310
goto exit;
10311
}
10312
10313
if (addr > 0x3FFF) {
10314
RTW_INFO(FUNC_ADPT_FMT" addr:0x%lx\n", FUNC_ADPT_ARG(padapter), addr);
10315
ret = -EINVAL;
10316
goto exit;
10317
}
10318
10319
if (DBG_MP_SDIO_INDIRECT_ACCESS)
10320
RTW_INFO(FUNC_ADPT_FMT" width:%u, addr:0x%lx, data:0x%lx\n", FUNC_ADPT_ARG(padapter), width, addr, data);
10321
10322
switch (width) {
10323
case 1:
10324
if (data > 0xFF) {
10325
ret = -EINVAL;
10326
break;
10327
}
10328
rtw_sd_iwrite8(padapter, addr, data);
10329
break;
10330
case 2:
10331
if (data > 0xFFFF) {
10332
ret = -EINVAL;
10333
break;
10334
}
10335
rtw_sd_iwrite16(padapter, addr, data);
10336
break;
10337
case 4:
10338
rtw_sd_iwrite32(padapter, addr, data);
10339
break;
10340
default:
10341
wrqu->length = 0;
10342
ret = -EINVAL;
10343
break;
10344
}
10345
10346
exit:
10347
return ret;
10348
}
10349
#endif /* CONFIG_SDIO_INDIRECT_ACCESS */
10350
10351
static int rtw_priv_set(struct net_device *dev,
10352
struct iw_request_info *info,
10353
union iwreq_data *wdata, char *extra)
10354
{
10355
struct iw_point *wrqu = (struct iw_point *)wdata;
10356
u32 subcmd = wrqu->flags;
10357
PADAPTER padapter = rtw_netdev_priv(dev);
10358
10359
if (padapter == NULL)
10360
return -ENETDOWN;
10361
10362
if (padapter->bup == _FALSE) {
10363
RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10364
return -ENETDOWN;
10365
}
10366
10367
if (RTW_CANNOT_RUN(padapter)) {
10368
RTW_INFO("%s fail =>(bSurpriseRemoved == _TRUE) || ( bDriverStopped == _TRUE)\n", __func__);
10369
return -ENETDOWN;
10370
}
10371
10372
if (extra == NULL) {
10373
wrqu->length = 0;
10374
return -EIO;
10375
}
10376
10377
if (subcmd < MP_NULL) {
10378
#ifdef CONFIG_MP_INCLUDED
10379
rtw_priv_mp_set(dev, info, wdata, extra);
10380
#endif
10381
return 0;
10382
}
10383
10384
switch (subcmd) {
10385
#ifdef CONFIG_WOWLAN
10386
case MP_WOW_ENABLE:
10387
RTW_INFO("set case MP_WOW_ENABLE: %s\n", extra);
10388
10389
rtw_wowlan_ctrl(dev, info, wdata, extra);
10390
break;
10391
case MP_WOW_SET_PATTERN:
10392
RTW_INFO("set case MP_WOW_SET_PATTERN: %s\n", extra);
10393
rtw_wowlan_set_pattern(dev, info, wdata, extra);
10394
break;
10395
#endif
10396
#ifdef CONFIG_AP_WOWLAN
10397
case MP_AP_WOW_ENABLE:
10398
RTW_INFO("set case MP_AP_WOW_ENABLE: %s\n", extra);
10399
rtw_ap_wowlan_ctrl(dev, info, wdata, extra);
10400
break;
10401
#endif
10402
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10403
case VENDOR_IE_SET:
10404
RTW_INFO("set case VENDOR_IE_SET\n");
10405
rtw_vendor_ie_set(dev , info , wdata , extra);
10406
break;
10407
#endif
10408
default:
10409
return -EIO;
10410
}
10411
10412
return 0;
10413
}
10414
10415
10416
static int rtw_priv_get(struct net_device *dev,
10417
struct iw_request_info *info,
10418
union iwreq_data *wdata, char *extra)
10419
{
10420
struct iw_point *wrqu = (struct iw_point *)wdata;
10421
u32 subcmd = wrqu->flags;
10422
PADAPTER padapter = rtw_netdev_priv(dev);
10423
10424
10425
if (padapter == NULL)
10426
return -ENETDOWN;
10427
10428
if (padapter->bup == _FALSE) {
10429
RTW_INFO(" %s fail =>(padapter->bup == _FALSE )\n", __FUNCTION__);
10430
return -ENETDOWN;
10431
}
10432
10433
if (RTW_CANNOT_RUN(padapter)) {
10434
RTW_INFO("%s fail =>(padapter->bSurpriseRemoved == _TRUE) || ( padapter->bDriverStopped == _TRUE)\n", __func__);
10435
return -ENETDOWN;
10436
}
10437
10438
if (extra == NULL) {
10439
wrqu->length = 0;
10440
return -EIO;
10441
}
10442
10443
if (subcmd < MP_NULL) {
10444
#ifdef CONFIG_MP_INCLUDED
10445
rtw_priv_mp_get(dev, info, wdata, extra);
10446
rtw_msleep_os(10); /* delay 5ms for sending pkt before exit adb shell operation */
10447
#endif
10448
} else {
10449
switch (subcmd) {
10450
#if defined(CONFIG_RTL8723B)
10451
case MP_SetBT:
10452
RTW_INFO("set MP_SetBT\n");
10453
rtw_mp_SetBT(dev, info, wdata, extra);
10454
break;
10455
#endif
10456
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
10457
case MP_SD_IREAD:
10458
rtw_mp_sd_iread(dev, info, wrqu, extra);
10459
break;
10460
case MP_SD_IWRITE:
10461
rtw_mp_sd_iwrite(dev, info, wrqu, extra);
10462
break;
10463
#endif
10464
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
10465
case VENDOR_IE_GET:
10466
RTW_INFO("get case VENDOR_IE_GET\n");
10467
rtw_vendor_ie_get(dev , info , wdata , extra);
10468
break;
10469
#endif
10470
default:
10471
return -EIO;
10472
}
10473
}
10474
10475
return 0;
10476
}
10477
10478
10479
#ifdef CONFIG_TDLS
10480
static int rtw_wx_tdls_wfd_enable(struct net_device *dev,
10481
struct iw_request_info *info,
10482
union iwreq_data *wrqu, char *extra)
10483
{
10484
int ret = 0;
10485
10486
#ifdef CONFIG_WFD
10487
10488
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10489
10490
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10491
10492
if (extra[0] == '0')
10493
rtw_tdls_wfd_enable(padapter, 0);
10494
else
10495
rtw_tdls_wfd_enable(padapter, 1);
10496
10497
#endif /* CONFIG_WFD */
10498
10499
return ret;
10500
}
10501
10502
static int rtw_tdls_weaksec(struct net_device *dev,
10503
struct iw_request_info *info,
10504
union iwreq_data *wrqu, char *extra)
10505
{
10506
int ret = 0;
10507
10508
#ifdef CONFIG_TDLS
10509
10510
u8 i, j;
10511
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10512
10513
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10514
10515
if (extra[0] == '0')
10516
padapter->wdinfo.wfd_tdls_weaksec = 0;
10517
else
10518
padapter->wdinfo.wfd_tdls_weaksec = 1;
10519
10520
#endif /* CONFIG_TDLS */
10521
10522
return ret;
10523
}
10524
10525
10526
static int rtw_tdls_enable(struct net_device *dev,
10527
struct iw_request_info *info,
10528
union iwreq_data *wrqu, char *extra)
10529
{
10530
int ret = 0;
10531
10532
#ifdef CONFIG_TDLS
10533
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10534
10535
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10536
10537
if (extra[0] == '0')
10538
rtw_disable_tdls_func(padapter, _TRUE);
10539
else if (extra[0] == '1')
10540
rtw_enable_tdls_func(padapter);
10541
#endif /* CONFIG_TDLS */
10542
10543
return ret;
10544
}
10545
10546
static int rtw_tdls_setup(struct net_device *dev,
10547
struct iw_request_info *info,
10548
union iwreq_data *wrqu, char *extra)
10549
{
10550
int ret = 0;
10551
#ifdef CONFIG_TDLS
10552
u8 i, j;
10553
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10554
struct tdls_txmgmt txmgmt;
10555
#ifdef CONFIG_WFD
10556
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
10557
#endif /* CONFIG_WFD */
10558
10559
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10560
10561
if (wrqu->data.length - 1 != 17) {
10562
RTW_INFO("[%s] length:%d != 17\n", __FUNCTION__, (wrqu->data.length - 1));
10563
return ret;
10564
}
10565
10566
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10567
for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10568
txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10569
10570
#ifdef CONFIG_WFD
10571
if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
10572
/* Weak Security situation with AP. */
10573
if (0 == pwdinfo->wfd_tdls_weaksec) {
10574
/* Can't send the tdls setup request out!! */
10575
RTW_INFO("[%s] Current link is not AES, "
10576
"SKIP sending the tdls setup request!!\n", __FUNCTION__);
10577
} else
10578
issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10579
} else
10580
#endif /* CONFIG_WFD */
10581
{
10582
issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
10583
}
10584
#endif /* CONFIG_TDLS */
10585
10586
return ret;
10587
}
10588
10589
static int rtw_tdls_teardown(struct net_device *dev,
10590
struct iw_request_info *info,
10591
union iwreq_data *wrqu, char *extra)
10592
{
10593
int ret = 0;
10594
10595
#ifdef CONFIG_TDLS
10596
10597
u8 i, j;
10598
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10599
struct sta_info *ptdls_sta = NULL;
10600
struct tdls_txmgmt txmgmt;
10601
10602
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10603
10604
if (wrqu->data.length - 1 != 17 && wrqu->data.length - 1 != 19) {
10605
RTW_INFO("[%s] length:%d != 17 or 19\n",
10606
__FUNCTION__, (wrqu->data.length - 1));
10607
return ret;
10608
}
10609
10610
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10611
for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
10612
txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10613
10614
ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
10615
10616
if (ptdls_sta != NULL) {
10617
txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
10618
if (wrqu->data.length - 1 == 19)
10619
issue_tdls_teardown(padapter, &txmgmt, _FALSE);
10620
else
10621
issue_tdls_teardown(padapter, &txmgmt, _TRUE);
10622
} else
10623
RTW_INFO("TDLS peer not found\n");
10624
#endif /* CONFIG_TDLS */
10625
10626
return ret;
10627
}
10628
10629
static int rtw_tdls_discovery(struct net_device *dev,
10630
struct iw_request_info *info,
10631
union iwreq_data *wrqu, char *extra)
10632
{
10633
int ret = 0;
10634
10635
#ifdef CONFIG_TDLS
10636
10637
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10638
struct tdls_txmgmt txmgmt;
10639
int i = 0, j = 0;
10640
10641
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10642
10643
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10644
for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10645
txmgmt.peer[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10646
10647
issue_tdls_dis_req(padapter, &txmgmt);
10648
10649
#endif /* CONFIG_TDLS */
10650
10651
return ret;
10652
}
10653
10654
static int rtw_tdls_ch_switch(struct net_device *dev,
10655
struct iw_request_info *info,
10656
union iwreq_data *wrqu, char *extra)
10657
{
10658
int ret = 0;
10659
10660
#ifdef CONFIG_TDLS
10661
#ifdef CONFIG_TDLS_CH_SW
10662
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10663
struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
10664
u8 i, j;
10665
struct sta_info *ptdls_sta = NULL;
10666
u8 take_care_iqk;
10667
10668
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10669
10670
if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
10671
RTW_INFO("TDLS channel switch is not allowed\n");
10672
return ret;
10673
}
10674
10675
for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10676
pchsw_info->addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10677
10678
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, pchsw_info->addr);
10679
if (ptdls_sta == NULL)
10680
return ret;
10681
10682
pchsw_info->ch_sw_state |= TDLS_CH_SW_INITIATOR_STATE;
10683
10684
if (ptdls_sta != NULL) {
10685
if (pchsw_info->off_ch_num == 0)
10686
pchsw_info->off_ch_num = 11;
10687
} else
10688
RTW_INFO("TDLS peer not found\n");
10689
10690
rtw_pm_set_lps(padapter, PS_MODE_ACTIVE);
10691
10692
rtw_hal_get_hwreg(padapter, HW_VAR_CH_SW_NEED_TO_TAKE_CARE_IQK_INFO, &take_care_iqk);
10693
if (take_care_iqk == _TRUE) {
10694
u8 central_chnl;
10695
u8 bw_mode;
10696
10697
bw_mode = (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20;
10698
central_chnl = rtw_get_center_ch(pchsw_info->off_ch_num, bw_mode, pchsw_info->ch_offset);
10699
if (rtw_hal_ch_sw_iqk_info_search(padapter, central_chnl, bw_mode) >= 0)
10700
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
10701
else
10702
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_PREPARE);
10703
} else
10704
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
10705
10706
/* issue_tdls_ch_switch_req(padapter, ptdls_sta); */
10707
/* RTW_INFO("issue tdls ch switch req\n"); */
10708
10709
#endif /* CONFIG_TDLS_CH_SW */
10710
#endif /* CONFIG_TDLS */
10711
10712
return ret;
10713
}
10714
10715
static int rtw_tdls_ch_switch_off(struct net_device *dev,
10716
struct iw_request_info *info,
10717
union iwreq_data *wrqu, char *extra)
10718
{
10719
int ret = 0;
10720
10721
#ifdef CONFIG_TDLS
10722
#ifdef CONFIG_TDLS_CH_SW
10723
10724
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10725
struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
10726
u8 i, j, mac_addr[ETH_ALEN];
10727
struct sta_info *ptdls_sta = NULL;
10728
struct tdls_txmgmt txmgmt;
10729
10730
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
10731
10732
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10733
10734
if (rtw_tdls_is_chsw_allowed(padapter) == _FALSE) {
10735
RTW_INFO("TDLS channel switch is not allowed\n");
10736
return ret;
10737
}
10738
10739
if (wrqu->data.length >= 17) {
10740
for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
10741
mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10742
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
10743
}
10744
10745
if (ptdls_sta == NULL)
10746
return ret;
10747
10748
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
10749
10750
pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
10751
TDLS_CH_SWITCH_ON_STATE |
10752
TDLS_PEER_AT_OFF_STATE);
10753
_rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
10754
10755
ptdls_sta->ch_switch_time = 0;
10756
ptdls_sta->ch_switch_timeout = 0;
10757
_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
10758
_cancel_timer_ex(&ptdls_sta->delay_timer);
10759
_cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
10760
_cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
10761
10762
rtw_pm_set_lps(padapter, PS_MODE_MAX);
10763
#endif /* CONFIG_TDLS_CH_SW */
10764
#endif /* CONFIG_TDLS */
10765
10766
return ret;
10767
}
10768
10769
static int rtw_tdls_dump_ch(struct net_device *dev,
10770
struct iw_request_info *info,
10771
union iwreq_data *wrqu, char *extra)
10772
{
10773
int ret = 0;
10774
10775
#ifdef CONFIG_TDLS
10776
#ifdef CONFIG_TDLS_CH_SW
10777
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10778
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10779
10780
RTW_INFO("[%s] dump_stack:%s\n", __FUNCTION__, extra);
10781
10782
extra[wrqu->data.length] = 0x00;
10783
ptdlsinfo->chsw_info.dump_stack = rtw_atoi(extra);
10784
10785
return ret;
10786
10787
#endif
10788
#endif /* CONFIG_TDLS */
10789
10790
return ret;
10791
}
10792
10793
static int rtw_tdls_off_ch_num(struct net_device *dev,
10794
struct iw_request_info *info,
10795
union iwreq_data *wrqu, char *extra)
10796
{
10797
int ret = 0;
10798
10799
#ifdef CONFIG_TDLS
10800
#ifdef CONFIG_TDLS_CH_SW
10801
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10802
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10803
10804
RTW_INFO("[%s] off_ch_num:%s\n", __FUNCTION__, extra);
10805
10806
extra[wrqu->data.length] = 0x00;
10807
ptdlsinfo->chsw_info.off_ch_num = rtw_atoi(extra);
10808
10809
return ret;
10810
10811
#endif
10812
#endif /* CONFIG_TDLS */
10813
10814
return ret;
10815
}
10816
10817
static int rtw_tdls_ch_offset(struct net_device *dev,
10818
struct iw_request_info *info,
10819
union iwreq_data *wrqu, char *extra)
10820
{
10821
int ret = 0;
10822
10823
#ifdef CONFIG_TDLS
10824
#ifdef CONFIG_TDLS_CH_SW
10825
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10826
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10827
10828
RTW_INFO("[%s] ch_offset:%s\n", __FUNCTION__, extra);
10829
10830
extra[wrqu->data.length] = 0x00;
10831
switch (rtw_atoi(extra)) {
10832
case SCA:
10833
ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
10834
break;
10835
10836
case SCB:
10837
ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
10838
break;
10839
10840
default:
10841
ptdlsinfo->chsw_info.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
10842
break;
10843
}
10844
10845
return ret;
10846
10847
#endif
10848
#endif /* CONFIG_TDLS */
10849
10850
return ret;
10851
}
10852
10853
static int rtw_tdls_pson(struct net_device *dev,
10854
struct iw_request_info *info,
10855
union iwreq_data *wrqu, char *extra)
10856
{
10857
int ret = 0;
10858
10859
#ifdef CONFIG_TDLS
10860
10861
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10862
u8 i, j, mac_addr[ETH_ALEN];
10863
struct sta_info *ptdls_sta = NULL;
10864
10865
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10866
10867
for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
10868
mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10869
10870
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
10871
10872
issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 1, 3, 500);
10873
10874
#endif /* CONFIG_TDLS */
10875
10876
return ret;
10877
}
10878
10879
static int rtw_tdls_psoff(struct net_device *dev,
10880
struct iw_request_info *info,
10881
union iwreq_data *wrqu, char *extra)
10882
{
10883
int ret = 0;
10884
10885
#ifdef CONFIG_TDLS
10886
10887
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10888
u8 i, j, mac_addr[ETH_ALEN];
10889
struct sta_info *ptdls_sta = NULL;
10890
10891
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10892
10893
for (i = 0, j = 0; i < ETH_ALEN; i++, j += 3)
10894
mac_addr[i] = key_2char2num(*(extra + j), *(extra + j + 1));
10895
10896
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, mac_addr);
10897
10898
if (ptdls_sta)
10899
issue_nulldata_to_TDLS_peer_STA(padapter, ptdls_sta->cmn.mac_addr, 0, 3, 500);
10900
10901
#endif /* CONFIG_TDLS */
10902
10903
return ret;
10904
}
10905
10906
static int rtw_tdls_setip(struct net_device *dev,
10907
struct iw_request_info *info,
10908
union iwreq_data *wrqu, char *extra)
10909
{
10910
int ret = 0;
10911
10912
#ifdef CONFIG_TDLS
10913
#ifdef CONFIG_WFD
10914
10915
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10916
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10917
struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
10918
u8 i = 0, j = 0, k = 0, tag = 0;
10919
10920
RTW_INFO("[%s] %s %d\n", __FUNCTION__, extra, wrqu->data.length - 1);
10921
10922
while (i < 4) {
10923
for (j = 0; j < 4; j++) {
10924
if (*(extra + j + tag) == '.' || *(extra + j + tag) == '\0') {
10925
if (j == 1)
10926
pwfd_info->ip_address[i] = convert_ip_addr('0', '0', *(extra + (j - 1) + tag));
10927
if (j == 2)
10928
pwfd_info->ip_address[i] = convert_ip_addr('0', *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
10929
if (j == 3)
10930
pwfd_info->ip_address[i] = convert_ip_addr(*(extra + (j - 3) + tag), *(extra + (j - 2) + tag), *(extra + (j - 1) + tag));
10931
10932
tag += j + 1;
10933
break;
10934
}
10935
}
10936
i++;
10937
}
10938
10939
RTW_INFO("[%s] Set IP = %u.%u.%u.%u\n", __FUNCTION__,
10940
ptdlsinfo->wfd_info->ip_address[0],
10941
ptdlsinfo->wfd_info->ip_address[1],
10942
ptdlsinfo->wfd_info->ip_address[2],
10943
ptdlsinfo->wfd_info->ip_address[3]);
10944
10945
#endif /* CONFIG_WFD */
10946
#endif /* CONFIG_TDLS */
10947
10948
return ret;
10949
}
10950
10951
static int rtw_tdls_getip(struct net_device *dev,
10952
struct iw_request_info *info,
10953
union iwreq_data *wrqu, char *extra)
10954
{
10955
int ret = 0;
10956
10957
#ifdef CONFIG_TDLS
10958
#ifdef CONFIG_WFD
10959
10960
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10961
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10962
struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
10963
10964
RTW_INFO("[%s]\n", __FUNCTION__);
10965
10966
sprintf(extra, "\n\n%u.%u.%u.%u\n",
10967
pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
10968
pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
10969
10970
RTW_INFO("[%s] IP=%u.%u.%u.%u\n", __FUNCTION__,
10971
pwfd_info->peer_ip_address[0], pwfd_info->peer_ip_address[1],
10972
pwfd_info->peer_ip_address[2], pwfd_info->peer_ip_address[3]);
10973
10974
wrqu->data.length = strlen(extra);
10975
10976
#endif /* CONFIG_WFD */
10977
#endif /* CONFIG_TDLS */
10978
10979
return ret;
10980
}
10981
10982
static int rtw_tdls_getport(struct net_device *dev,
10983
struct iw_request_info *info,
10984
union iwreq_data *wrqu, char *extra)
10985
{
10986
10987
int ret = 0;
10988
10989
#ifdef CONFIG_TDLS
10990
#ifdef CONFIG_WFD
10991
10992
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
10993
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
10994
struct wifi_display_info *pwfd_info = ptdlsinfo->wfd_info;
10995
10996
RTW_INFO("[%s]\n", __FUNCTION__);
10997
10998
sprintf(extra, "\n\n%d\n", pwfd_info->peer_rtsp_ctrlport);
10999
RTW_INFO("[%s] remote port = %d\n",
11000
__FUNCTION__, pwfd_info->peer_rtsp_ctrlport);
11001
11002
wrqu->data.length = strlen(extra);
11003
11004
#endif /* CONFIG_WFD */
11005
#endif /* CONFIG_TDLS */
11006
11007
return ret;
11008
11009
}
11010
11011
/* WFDTDLS, for sigma test */
11012
static int rtw_tdls_dis_result(struct net_device *dev,
11013
struct iw_request_info *info,
11014
union iwreq_data *wrqu, char *extra)
11015
{
11016
11017
int ret = 0;
11018
11019
#ifdef CONFIG_TDLS
11020
#ifdef CONFIG_WFD
11021
11022
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11023
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11024
11025
RTW_INFO("[%s]\n", __FUNCTION__);
11026
11027
if (ptdlsinfo->dev_discovered == _TRUE) {
11028
sprintf(extra, "\n\nDis=1\n");
11029
ptdlsinfo->dev_discovered = _FALSE;
11030
}
11031
11032
wrqu->data.length = strlen(extra);
11033
11034
#endif /* CONFIG_WFD */
11035
#endif /* CONFIG_TDLS */
11036
11037
return ret;
11038
11039
}
11040
11041
/* WFDTDLS, for sigma test */
11042
static int rtw_wfd_tdls_status(struct net_device *dev,
11043
struct iw_request_info *info,
11044
union iwreq_data *wrqu, char *extra)
11045
{
11046
11047
int ret = 0;
11048
11049
#ifdef CONFIG_TDLS
11050
11051
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11052
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
11053
11054
RTW_INFO("[%s]\n", __FUNCTION__);
11055
11056
sprintf(extra, "\nlink_established:%d\n"
11057
"sta_cnt:%d\n"
11058
"sta_maximum:%d\n"
11059
"cur_channel:%d\n"
11060
"tdls_enable:%d"
11061
#ifdef CONFIG_TDLS_CH_SW
11062
"ch_sw_state:%08x\n"
11063
"chsw_on:%d\n"
11064
"off_ch_num:%d\n"
11065
"cur_time:%d\n"
11066
"ch_offset:%d\n"
11067
"delay_swtich_back:%d"
11068
#endif
11069
,
11070
ptdlsinfo->link_established, ptdlsinfo->sta_cnt,
11071
ptdlsinfo->sta_maximum, ptdlsinfo->cur_channel,
11072
rtw_is_tdls_enabled(padapter)
11073
#ifdef CONFIG_TDLS_CH_SW
11074
,
11075
ptdlsinfo->chsw_info.ch_sw_state,
11076
ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on),
11077
ptdlsinfo->chsw_info.off_ch_num,
11078
ptdlsinfo->chsw_info.cur_time,
11079
ptdlsinfo->chsw_info.ch_offset,
11080
ptdlsinfo->chsw_info.delay_switch_back
11081
#endif
11082
);
11083
11084
wrqu->data.length = strlen(extra);
11085
11086
#endif /* CONFIG_TDLS */
11087
11088
return ret;
11089
11090
}
11091
11092
static int rtw_tdls_getsta(struct net_device *dev,
11093
struct iw_request_info *info,
11094
union iwreq_data *wrqu, char *extra)
11095
{
11096
11097
int ret = 0;
11098
#ifdef CONFIG_TDLS
11099
u8 i, j;
11100
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11101
u8 addr[ETH_ALEN] = {0};
11102
char charmac[17];
11103
struct sta_info *ptdls_sta = NULL;
11104
11105
RTW_INFO("[%s] %s %d\n", __FUNCTION__,
11106
(char *)wrqu->data.pointer, wrqu->data.length - 1);
11107
11108
if (copy_from_user(charmac, wrqu->data.pointer + 9, 17)) {
11109
ret = -EFAULT;
11110
goto exit;
11111
}
11112
11113
RTW_INFO("[%s] %d, charmac:%s\n", __FUNCTION__, __LINE__, charmac);
11114
for (i = 0, j = 0 ; i < ETH_ALEN; i++, j += 3)
11115
addr[i] = key_2char2num(*(charmac + j), *(charmac + j + 1));
11116
11117
RTW_INFO("[%s] %d, charmac:%s, addr:"MAC_FMT"\n",
11118
__FUNCTION__, __LINE__, charmac, MAC_ARG(addr));
11119
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, addr);
11120
if (ptdls_sta) {
11121
sprintf(extra, "\n\ntdls_sta_state=0x%08x\n", ptdls_sta->tdls_sta_state);
11122
RTW_INFO("\n\ntdls_sta_state=%d\n", ptdls_sta->tdls_sta_state);
11123
} else {
11124
sprintf(extra, "\n\nNot found this sta\n");
11125
RTW_INFO("\n\nNot found this sta\n");
11126
}
11127
wrqu->data.length = strlen(extra);
11128
11129
exit:
11130
#endif /* CONFIG_TDLS */
11131
return ret;
11132
11133
}
11134
11135
static int rtw_tdls_get_best_ch(struct net_device *dev,
11136
struct iw_request_info *info,
11137
union iwreq_data *wrqu, char *extra)
11138
{
11139
#ifdef CONFIG_FIND_BEST_CHANNEL
11140
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11141
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
11142
u32 i, best_channel_24G = 1, best_channel_5G = 36, index_24G = 0, index_5G = 0;
11143
11144
for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {
11145
if (rfctl->channel_set[i].ChannelNum == 1)
11146
index_24G = i;
11147
if (rfctl->channel_set[i].ChannelNum == 36)
11148
index_5G = i;
11149
}
11150
11151
for (i = 0; i < rfctl->max_chan_nums && rfctl->channel_set[i].ChannelNum != 0; i++) {
11152
/* 2.4G */
11153
if (rfctl->channel_set[i].ChannelNum == 6 || rfctl->channel_set[i].ChannelNum == 11) {
11154
if (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_24G].rx_count) {
11155
index_24G = i;
11156
best_channel_24G = rfctl->channel_set[i].ChannelNum;
11157
}
11158
}
11159
11160
/* 5G */
11161
if (rfctl->channel_set[i].ChannelNum >= 36
11162
&& rfctl->channel_set[i].ChannelNum < 140) {
11163
/* Find primary channel */
11164
if (((rfctl->channel_set[i].ChannelNum - 36) % 8 == 0)
11165
&& (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {
11166
index_5G = i;
11167
best_channel_5G = rfctl->channel_set[i].ChannelNum;
11168
}
11169
}
11170
11171
if (rfctl->channel_set[i].ChannelNum >= 149
11172
&& rfctl->channel_set[i].ChannelNum < 165) {
11173
/* Find primary channel */
11174
if (((rfctl->channel_set[i].ChannelNum - 149) % 8 == 0)
11175
&& (rfctl->channel_set[i].rx_count < rfctl->channel_set[index_5G].rx_count)) {
11176
index_5G = i;
11177
best_channel_5G = rfctl->channel_set[i].ChannelNum;
11178
}
11179
}
11180
#if 1 /* debug */
11181
RTW_INFO("The rx cnt of channel %3d = %d\n",
11182
rfctl->channel_set[i].ChannelNum,
11183
rfctl->channel_set[i].rx_count);
11184
#endif
11185
}
11186
11187
sprintf(extra, "\nbest_channel_24G = %d\n", best_channel_24G);
11188
RTW_INFO("best_channel_24G = %d\n", best_channel_24G);
11189
11190
if (index_5G != 0) {
11191
sprintf(extra, "best_channel_5G = %d\n", best_channel_5G);
11192
RTW_INFO("best_channel_5G = %d\n", best_channel_5G);
11193
}
11194
11195
wrqu->data.length = strlen(extra);
11196
11197
#endif
11198
11199
return 0;
11200
11201
}
11202
#endif /*#ifdef CONFIG_TDLS*/
11203
static int rtw_tdls(struct net_device *dev,
11204
struct iw_request_info *info,
11205
union iwreq_data *wrqu, char *extra)
11206
{
11207
int ret = 0;
11208
11209
#ifdef CONFIG_TDLS
11210
11211
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
11212
11213
RTW_INFO("[%s] extra = %s\n", __FUNCTION__, extra);
11214
11215
if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
11216
RTW_INFO("Discard tdls oper since hal doesn't support tdls\n");
11217
return 0;
11218
}
11219
11220
if (rtw_is_tdls_enabled(padapter) == _FALSE) {
11221
RTW_INFO("TDLS is not enabled\n");
11222
return 0;
11223
}
11224
11225
/* WFD Sigma will use the tdls enable command to let the driver know we want to test the tdls now! */
11226
11227
if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11228
if (_rtw_memcmp(extra, "wfdenable=", 10)) {
11229
wrqu->data.length -= 10;
11230
rtw_wx_tdls_wfd_enable(dev, info, wrqu, &extra[10]);
11231
return ret;
11232
}
11233
}
11234
11235
if (_rtw_memcmp(extra, "weaksec=", 8)) {
11236
wrqu->data.length -= 8;
11237
rtw_tdls_weaksec(dev, info, wrqu, &extra[8]);
11238
return ret;
11239
} else if (_rtw_memcmp(extra, "tdlsenable=", 11)) {
11240
wrqu->data.length -= 11;
11241
rtw_tdls_enable(dev, info, wrqu, &extra[11]);
11242
return ret;
11243
}
11244
11245
if (_rtw_memcmp(extra, "setup=", 6)) {
11246
wrqu->data.length -= 6;
11247
rtw_tdls_setup(dev, info, wrqu, &extra[6]);
11248
} else if (_rtw_memcmp(extra, "tear=", 5)) {
11249
wrqu->data.length -= 5;
11250
rtw_tdls_teardown(dev, info, wrqu, &extra[5]);
11251
} else if (_rtw_memcmp(extra, "dis=", 4)) {
11252
wrqu->data.length -= 4;
11253
rtw_tdls_discovery(dev, info, wrqu, &extra[4]);
11254
} else if (_rtw_memcmp(extra, "swoff=", 6)) {
11255
wrqu->data.length -= 6;
11256
rtw_tdls_ch_switch_off(dev, info, wrqu, &extra[6]);
11257
} else if (_rtw_memcmp(extra, "sw=", 3)) {
11258
wrqu->data.length -= 3;
11259
rtw_tdls_ch_switch(dev, info, wrqu, &extra[3]);
11260
} else if (_rtw_memcmp(extra, "dumpstack=", 10)) {
11261
wrqu->data.length -= 10;
11262
rtw_tdls_dump_ch(dev, info, wrqu, &extra[10]);
11263
} else if (_rtw_memcmp(extra, "offchnum=", 9)) {
11264
wrqu->data.length -= 9;
11265
rtw_tdls_off_ch_num(dev, info, wrqu, &extra[9]);
11266
} else if (_rtw_memcmp(extra, "choffset=", 9)) {
11267
wrqu->data.length -= 9;
11268
rtw_tdls_ch_offset(dev, info, wrqu, &extra[9]);
11269
} else if (_rtw_memcmp(extra, "pson=", 5)) {
11270
wrqu->data.length -= 5;
11271
rtw_tdls_pson(dev, info, wrqu, &extra[5]);
11272
} else if (_rtw_memcmp(extra, "psoff=", 6)) {
11273
wrqu->data.length -= 6;
11274
rtw_tdls_psoff(dev, info, wrqu, &extra[6]);
11275
}
11276
11277
#ifdef CONFIG_WFD
11278
if (hal_chk_wl_func(padapter, WL_FUNC_MIRACAST)) {
11279
if (_rtw_memcmp(extra, "setip=", 6)) {
11280
wrqu->data.length -= 6;
11281
rtw_tdls_setip(dev, info, wrqu, &extra[6]);
11282
} else if (_rtw_memcmp(extra, "tprobe=", 6))
11283
issue_tunneled_probe_req((_adapter *)rtw_netdev_priv(dev));
11284
}
11285
#endif /* CONFIG_WFD */
11286
11287
#endif /* CONFIG_TDLS */
11288
11289
return ret;
11290
}
11291
11292
11293
static int rtw_tdls_get(struct net_device *dev,
11294
struct iw_request_info *info,
11295
union iwreq_data *wrqu, char *extra)
11296
{
11297
int ret = 0;
11298
11299
#ifdef CONFIG_TDLS
11300
11301
RTW_INFO("[%s] extra = %s\n", __FUNCTION__, (char *) wrqu->data.pointer);
11302
11303
if (_rtw_memcmp(wrqu->data.pointer, "ip", 2))
11304
rtw_tdls_getip(dev, info, wrqu, extra);
11305
else if (_rtw_memcmp(wrqu->data.pointer, "port", 4))
11306
rtw_tdls_getport(dev, info, wrqu, extra);
11307
/* WFDTDLS, for sigma test */
11308
else if (_rtw_memcmp(wrqu->data.pointer, "dis", 3))
11309
rtw_tdls_dis_result(dev, info, wrqu, extra);
11310
else if (_rtw_memcmp(wrqu->data.pointer, "status", 6))
11311
rtw_wfd_tdls_status(dev, info, wrqu, extra);
11312
else if (_rtw_memcmp(wrqu->data.pointer, "tdls_sta=", 9))
11313
rtw_tdls_getsta(dev, info, wrqu, extra);
11314
else if (_rtw_memcmp(wrqu->data.pointer, "best_ch", 7))
11315
rtw_tdls_get_best_ch(dev, info, wrqu, extra);
11316
#endif /* CONFIG_TDLS */
11317
11318
return ret;
11319
}
11320
11321
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
11322
11323
#if defined(CONFIG_RTL8188E)
11324
#include <rtl8188e_hal.h>
11325
extern void rtl8188e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11326
#define cal_txdesc_chksum rtl8188e_cal_txdesc_chksum
11327
#ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11328
extern void rtl8188es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11329
#define fill_default_txdesc rtl8188es_fill_default_txdesc
11330
#endif /* CONFIG_SDIO_HCI */
11331
#endif /* CONFIG_RTL8188E */
11332
#if defined(CONFIG_RTL8723B)
11333
extern void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11334
#define cal_txdesc_chksum rtl8723b_cal_txdesc_chksum
11335
extern void rtl8723b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11336
#define fill_default_txdesc rtl8723b_fill_default_txdesc
11337
#endif /* CONFIG_RTL8723B */
11338
11339
#if defined(CONFIG_RTL8703B)
11340
/* extern void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11341
#define cal_txdesc_chksum rtl8703b_cal_txdesc_chksum
11342
/* extern void rtl8703b_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11343
#define fill_default_txdesc rtl8703b_fill_default_txdesc
11344
#endif /* CONFIG_RTL8703B */
11345
11346
#if defined(CONFIG_RTL8723D)
11347
/* extern void rtl8723d_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11348
#define cal_txdesc_chksum rtl8723d_cal_txdesc_chksum
11349
/* extern void rtl8723d_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11350
#define fill_default_txdesc rtl8723d_fill_default_txdesc
11351
#endif /* CONFIG_RTL8723D */
11352
11353
#if defined(CONFIG_RTL8710B)
11354
#define cal_txdesc_chksum rtl8710b_cal_txdesc_chksum
11355
#define fill_default_txdesc rtl8710b_fill_default_txdesc
11356
#endif /* CONFIG_RTL8710B */
11357
11358
#if defined(CONFIG_RTL8192E)
11359
extern void rtl8192e_cal_txdesc_chksum(struct tx_desc *ptxdesc);
11360
#define cal_txdesc_chksum rtl8192e_cal_txdesc_chksum
11361
#ifdef CONFIG_SDIO_HCI || defined(CONFIG_GSPI_HCI)
11362
extern void rtl8192es_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf);
11363
#define fill_default_txdesc rtl8192es_fill_default_txdesc
11364
#endif /* CONFIG_SDIO_HCI */
11365
#endif /* CONFIG_RTL8192E */
11366
11367
#if defined(CONFIG_RTL8192F)
11368
/* extern void rtl8192f_cal_txdesc_chksum(struct tx_desc *ptxdesc); */
11369
#define cal_txdesc_chksum rtl8192f_cal_txdesc_chksum
11370
/* extern void rtl8192f_fill_default_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf); */
11371
#define fill_default_txdesc rtl8192f_fill_default_txdesc
11372
#endif /* CONFIG_RTL8192F */
11373
11374
static s32 initLoopback(PADAPTER padapter)
11375
{
11376
PLOOPBACKDATA ploopback;
11377
11378
11379
if (padapter->ploopback == NULL) {
11380
ploopback = (PLOOPBACKDATA)rtw_zmalloc(sizeof(LOOPBACKDATA));
11381
if (ploopback == NULL)
11382
return -ENOMEM;
11383
11384
_rtw_init_sema(&ploopback->sema, 0);
11385
ploopback->bstop = _TRUE;
11386
ploopback->cnt = 0;
11387
ploopback->size = 300;
11388
_rtw_memset(ploopback->msg, 0, sizeof(ploopback->msg));
11389
11390
padapter->ploopback = ploopback;
11391
}
11392
11393
return 0;
11394
}
11395
11396
static void freeLoopback(PADAPTER padapter)
11397
{
11398
PLOOPBACKDATA ploopback;
11399
11400
11401
ploopback = padapter->ploopback;
11402
if (ploopback) {
11403
rtw_mfree((u8 *)ploopback, sizeof(LOOPBACKDATA));
11404
padapter->ploopback = NULL;
11405
}
11406
}
11407
11408
static s32 initpseudoadhoc(PADAPTER padapter)
11409
{
11410
NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
11411
s32 err;
11412
11413
networkType = Ndis802_11IBSS;
11414
err = rtw_set_802_11_infrastructure_mode(padapter, networkType, 0);
11415
if (err == _FALSE)
11416
return _FAIL;
11417
11418
err = rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
11419
if (err == _FAIL)
11420
return _FAIL;
11421
11422
return _SUCCESS;
11423
}
11424
11425
static s32 createpseudoadhoc(PADAPTER padapter)
11426
{
11427
NDIS_802_11_AUTHENTICATION_MODE authmode;
11428
struct mlme_priv *pmlmepriv;
11429
NDIS_802_11_SSID *passoc_ssid;
11430
WLAN_BSSID_EX *pdev_network;
11431
u8 *pibss;
11432
u8 ssid[] = "pseduo_ad-hoc";
11433
s32 err;
11434
_irqL irqL;
11435
11436
11437
pmlmepriv = &padapter->mlmepriv;
11438
11439
authmode = Ndis802_11AuthModeOpen;
11440
err = rtw_set_802_11_authentication_mode(padapter, authmode);
11441
if (err == _FALSE)
11442
return _FAIL;
11443
11444
passoc_ssid = &pmlmepriv->assoc_ssid;
11445
_rtw_memset(passoc_ssid, 0, sizeof(NDIS_802_11_SSID));
11446
passoc_ssid->SsidLength = sizeof(ssid) - 1;
11447
_rtw_memcpy(passoc_ssid->Ssid, ssid, passoc_ssid->SsidLength);
11448
11449
pdev_network = &padapter->registrypriv.dev_network;
11450
pibss = padapter->registrypriv.dev_network.MacAddress;
11451
_rtw_memcpy(&pdev_network->Ssid, passoc_ssid, sizeof(NDIS_802_11_SSID));
11452
11453
rtw_update_registrypriv_dev_network(padapter);
11454
rtw_generate_random_ibss(pibss);
11455
11456
_enter_critical_bh(&pmlmepriv->lock, &irqL);
11457
/*pmlmepriv->fw_state = WIFI_ADHOC_MASTER_STATE;*/
11458
init_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE);
11459
11460
_exit_critical_bh(&pmlmepriv->lock, &irqL);
11461
11462
#if 0
11463
err = rtw_create_ibss_cmd(padapter, 0);
11464
if (err == _FAIL)
11465
return _FAIL;
11466
#else
11467
{
11468
struct wlan_network *pcur_network;
11469
struct sta_info *psta;
11470
11471
/* 3 create a new psta */
11472
pcur_network = &pmlmepriv->cur_network;
11473
11474
/* clear psta in the cur_network, if any */
11475
psta = rtw_get_stainfo(&padapter->stapriv, pcur_network->network.MacAddress);
11476
if (psta)
11477
rtw_free_stainfo(padapter, psta);
11478
11479
psta = rtw_alloc_stainfo(&padapter->stapriv, pibss);
11480
if (psta == NULL)
11481
return _FAIL;
11482
11483
/* 3 join psudo AdHoc */
11484
pcur_network->join_res = 1;
11485
pcur_network->aid = psta->cmn.aid = 1;
11486
_rtw_memcpy(&pcur_network->network, pdev_network, get_WLAN_BSSID_EX_sz(pdev_network));
11487
11488
/* set msr to WIFI_FW_ADHOC_STATE */
11489
padapter->hw_port = HW_PORT0;
11490
Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11491
11492
}
11493
#endif
11494
11495
return _SUCCESS;
11496
}
11497
11498
static struct xmit_frame *createloopbackpkt(PADAPTER padapter, u32 size)
11499
{
11500
struct xmit_priv *pxmitpriv;
11501
struct xmit_frame *pframe;
11502
struct xmit_buf *pxmitbuf;
11503
struct pkt_attrib *pattrib;
11504
struct tx_desc *desc;
11505
u8 *pkt_start, *pkt_end, *ptr;
11506
struct rtw_ieee80211_hdr *hdr;
11507
s32 bmcast;
11508
_irqL irqL;
11509
11510
11511
if ((TXDESC_SIZE + WLANHDR_OFFSET + size) > MAX_XMITBUF_SZ)
11512
return NULL;
11513
11514
pxmitpriv = &padapter->xmitpriv;
11515
pframe = NULL;
11516
11517
/* 2 1. allocate xmit frame */
11518
pframe = rtw_alloc_xmitframe(pxmitpriv);
11519
if (pframe == NULL)
11520
return NULL;
11521
pframe->padapter = padapter;
11522
11523
/* 2 2. allocate xmit buffer */
11524
_enter_critical_bh(&pxmitpriv->lock, &irqL);
11525
pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
11526
_exit_critical_bh(&pxmitpriv->lock, &irqL);
11527
if (pxmitbuf == NULL) {
11528
rtw_free_xmitframe(pxmitpriv, pframe);
11529
return NULL;
11530
}
11531
11532
pframe->pxmitbuf = pxmitbuf;
11533
pframe->buf_addr = pxmitbuf->pbuf;
11534
pxmitbuf->priv_data = pframe;
11535
11536
/* 2 3. update_attrib() */
11537
pattrib = &pframe->attrib;
11538
11539
/* init xmitframe attribute */
11540
_rtw_memset(pattrib, 0, sizeof(struct pkt_attrib));
11541
11542
pattrib->ether_type = 0x8723;
11543
_rtw_memcpy(pattrib->src, adapter_mac_addr(padapter), ETH_ALEN);
11544
_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
11545
_rtw_memset(pattrib->dst, 0xFF, ETH_ALEN);
11546
_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
11547
11548
/* pattrib->dhcp_pkt = 0;
11549
* pattrib->pktlen = 0; */
11550
pattrib->ack_policy = 0;
11551
/* pattrib->pkt_hdrlen = ETH_HLEN; */
11552
pattrib->hdrlen = WLAN_HDR_A3_LEN;
11553
pattrib->subtype = WIFI_DATA;
11554
pattrib->priority = 0;
11555
pattrib->qsel = pattrib->priority;
11556
/* do_queue_select(padapter, pattrib); */
11557
pattrib->nr_frags = 1;
11558
pattrib->encrypt = 0;
11559
pattrib->bswenc = _FALSE;
11560
pattrib->qos_en = _FALSE;
11561
11562
bmcast = IS_MCAST(pattrib->ra);
11563
if (bmcast)
11564
pattrib->psta = rtw_get_bcmc_stainfo(padapter);
11565
else
11566
pattrib->psta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
11567
11568
pattrib->mac_id = pattrib->psta->cmn.mac_id;
11569
pattrib->pktlen = size;
11570
pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->pktlen;
11571
11572
/* 2 4. fill TX descriptor */
11573
desc = (struct tx_desc *)pframe->buf_addr;
11574
_rtw_memset(desc, 0, TXDESC_SIZE);
11575
11576
fill_default_txdesc(pframe, (u8 *)desc);
11577
11578
/* Hw set sequence number */
11579
((PTXDESC)desc)->hwseq_en = 0; /* HWSEQ_EN, 0:disable, 1:enable
11580
* ((PTXDESC)desc)->hwseq_sel = 0; */ /* HWSEQ_SEL */
11581
11582
((PTXDESC)desc)->disdatafb = 1;
11583
11584
/* convert to little endian */
11585
desc->txdw0 = cpu_to_le32(desc->txdw0);
11586
desc->txdw1 = cpu_to_le32(desc->txdw1);
11587
desc->txdw2 = cpu_to_le32(desc->txdw2);
11588
desc->txdw3 = cpu_to_le32(desc->txdw3);
11589
desc->txdw4 = cpu_to_le32(desc->txdw4);
11590
desc->txdw5 = cpu_to_le32(desc->txdw5);
11591
desc->txdw6 = cpu_to_le32(desc->txdw6);
11592
desc->txdw7 = cpu_to_le32(desc->txdw7);
11593
#ifdef CONFIG_PCI_HCI
11594
desc->txdw8 = cpu_to_le32(desc->txdw8);
11595
desc->txdw9 = cpu_to_le32(desc->txdw9);
11596
desc->txdw10 = cpu_to_le32(desc->txdw10);
11597
desc->txdw11 = cpu_to_le32(desc->txdw11);
11598
desc->txdw12 = cpu_to_le32(desc->txdw12);
11599
desc->txdw13 = cpu_to_le32(desc->txdw13);
11600
desc->txdw14 = cpu_to_le32(desc->txdw14);
11601
desc->txdw15 = cpu_to_le32(desc->txdw15);
11602
#endif
11603
11604
cal_txdesc_chksum(desc);
11605
11606
/* 2 5. coalesce */
11607
pkt_start = pframe->buf_addr + TXDESC_SIZE;
11608
pkt_end = pkt_start + pattrib->last_txcmdsz;
11609
11610
/* 3 5.1. make wlan header, make_wlanhdr() */
11611
hdr = (struct rtw_ieee80211_hdr *)pkt_start;
11612
set_frame_sub_type(&hdr->frame_ctl, pattrib->subtype);
11613
_rtw_memcpy(hdr->addr1, pattrib->dst, ETH_ALEN); /* DA */
11614
_rtw_memcpy(hdr->addr2, pattrib->src, ETH_ALEN); /* SA */
11615
_rtw_memcpy(hdr->addr3, get_bssid(&padapter->mlmepriv), ETH_ALEN); /* RA, BSSID */
11616
11617
/* 3 5.2. make payload */
11618
ptr = pkt_start + pattrib->hdrlen;
11619
get_random_bytes(ptr, pkt_end - ptr);
11620
11621
pxmitbuf->len = TXDESC_SIZE + pattrib->last_txcmdsz;
11622
pxmitbuf->ptail += pxmitbuf->len;
11623
11624
return pframe;
11625
}
11626
11627
static void freeloopbackpkt(PADAPTER padapter, struct xmit_frame *pframe)
11628
{
11629
struct xmit_priv *pxmitpriv;
11630
struct xmit_buf *pxmitbuf;
11631
11632
11633
pxmitpriv = &padapter->xmitpriv;
11634
pxmitbuf = pframe->pxmitbuf;
11635
11636
rtw_free_xmitframe(pxmitpriv, pframe);
11637
rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
11638
}
11639
11640
static void printdata(u8 *pbuf, u32 len)
11641
{
11642
u32 i, val;
11643
11644
11645
for (i = 0; (i + 4) <= len; i += 4) {
11646
printk("%08X", *(u32 *)(pbuf + i));
11647
if ((i + 4) & 0x1F)
11648
printk(" ");
11649
else
11650
printk("\n");
11651
}
11652
11653
if (i < len) {
11654
#ifdef CONFIG_BIG_ENDIAN
11655
for (; i < len, i++)
11656
printk("%02X", pbuf + i);
11657
#else /* CONFIG_LITTLE_ENDIAN */
11658
#if 0
11659
val = 0;
11660
_rtw_memcpy(&val, pbuf + i, len - i);
11661
printk("%8X", val);
11662
#else
11663
u8 str[9];
11664
u8 n;
11665
val = 0;
11666
n = len - i;
11667
_rtw_memcpy(&val, pbuf + i, n);
11668
sprintf(str, "%08X", val);
11669
n = (4 - n) * 2;
11670
printk("%8s", str + n);
11671
#endif
11672
#endif /* CONFIG_LITTLE_ENDIAN */
11673
}
11674
printk("\n");
11675
}
11676
11677
static u8 pktcmp(PADAPTER padapter, u8 *txbuf, u32 txsz, u8 *rxbuf, u32 rxsz)
11678
{
11679
PHAL_DATA_TYPE phal;
11680
struct recv_stat *prxstat;
11681
struct recv_stat report;
11682
PRXREPORT prxreport;
11683
u32 drvinfosize;
11684
u32 rxpktsize;
11685
u8 fcssize;
11686
u8 ret = _FALSE;
11687
11688
prxstat = (struct recv_stat *)rxbuf;
11689
report.rxdw0 = le32_to_cpu(prxstat->rxdw0);
11690
report.rxdw1 = le32_to_cpu(prxstat->rxdw1);
11691
report.rxdw2 = le32_to_cpu(prxstat->rxdw2);
11692
report.rxdw3 = le32_to_cpu(prxstat->rxdw3);
11693
report.rxdw4 = le32_to_cpu(prxstat->rxdw4);
11694
report.rxdw5 = le32_to_cpu(prxstat->rxdw5);
11695
11696
prxreport = (PRXREPORT)&report;
11697
drvinfosize = prxreport->drvinfosize << 3;
11698
rxpktsize = prxreport->pktlen;
11699
11700
phal = GET_HAL_DATA(padapter);
11701
if (rtw_hal_rcr_check(padapter, RCR_APPFCS))
11702
fcssize = IEEE80211_FCS_LEN;
11703
else
11704
fcssize = 0;
11705
11706
if ((txsz - TXDESC_SIZE) != (rxpktsize - fcssize)) {
11707
RTW_INFO("%s: ERROR! size not match tx/rx=%d/%d !\n",
11708
__func__, txsz - TXDESC_SIZE, rxpktsize - fcssize);
11709
ret = _FALSE;
11710
} else {
11711
ret = _rtw_memcmp(txbuf + TXDESC_SIZE, \
11712
rxbuf + RXDESC_SIZE + drvinfosize, \
11713
txsz - TXDESC_SIZE);
11714
if (ret == _FALSE)
11715
RTW_INFO("%s: ERROR! pkt content mismatch!\n", __func__);
11716
}
11717
11718
if (ret == _FALSE) {
11719
RTW_INFO("\n%s: TX PKT total=%d, desc=%d, content=%d\n",
11720
__func__, txsz, TXDESC_SIZE, txsz - TXDESC_SIZE);
11721
RTW_INFO("%s: TX DESC size=%d\n", __func__, TXDESC_SIZE);
11722
printdata(txbuf, TXDESC_SIZE);
11723
RTW_INFO("%s: TX content size=%d\n", __func__, txsz - TXDESC_SIZE);
11724
printdata(txbuf + TXDESC_SIZE, txsz - TXDESC_SIZE);
11725
11726
RTW_INFO("\n%s: RX PKT read=%d offset=%d(%d,%d) content=%d\n",
11727
__func__, rxsz, RXDESC_SIZE + drvinfosize, RXDESC_SIZE, drvinfosize, rxpktsize);
11728
if (rxpktsize != 0) {
11729
RTW_INFO("%s: RX DESC size=%d\n", __func__, RXDESC_SIZE);
11730
printdata(rxbuf, RXDESC_SIZE);
11731
RTW_INFO("%s: RX drvinfo size=%d\n", __func__, drvinfosize);
11732
printdata(rxbuf + RXDESC_SIZE, drvinfosize);
11733
RTW_INFO("%s: RX content size=%d\n", __func__, rxpktsize);
11734
printdata(rxbuf + RXDESC_SIZE + drvinfosize, rxpktsize);
11735
} else {
11736
RTW_INFO("%s: RX data size=%d\n", __func__, rxsz);
11737
printdata(rxbuf, rxsz);
11738
}
11739
}
11740
11741
return ret;
11742
}
11743
11744
thread_return lbk_thread(thread_context context)
11745
{
11746
s32 err;
11747
PADAPTER padapter;
11748
PLOOPBACKDATA ploopback;
11749
struct xmit_frame *pxmitframe;
11750
u32 cnt, ok, fail, headerlen;
11751
u32 pktsize;
11752
u32 ff_hwaddr;
11753
11754
11755
padapter = (PADAPTER)context;
11756
ploopback = padapter->ploopback;
11757
if (ploopback == NULL)
11758
return -1;
11759
cnt = 0;
11760
ok = 0;
11761
fail = 0;
11762
11763
daemonize("%s", "RTW_LBK_THREAD");
11764
allow_signal(SIGTERM);
11765
11766
do {
11767
if (ploopback->size == 0) {
11768
get_random_bytes(&pktsize, 4);
11769
pktsize = (pktsize % 1535) + 1; /* 1~1535 */
11770
} else
11771
pktsize = ploopback->size;
11772
11773
pxmitframe = createloopbackpkt(padapter, pktsize);
11774
if (pxmitframe == NULL) {
11775
sprintf(ploopback->msg, "loopback FAIL! 3. create Packet FAIL!");
11776
break;
11777
}
11778
11779
ploopback->txsize = TXDESC_SIZE + pxmitframe->attrib.last_txcmdsz;
11780
_rtw_memcpy(ploopback->txbuf, pxmitframe->buf_addr, ploopback->txsize);
11781
ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
11782
cnt++;
11783
RTW_INFO("%s: wirte port cnt=%d size=%d\n", __func__, cnt, ploopback->txsize);
11784
pxmitframe->pxmitbuf->pdata = ploopback->txbuf;
11785
rtw_write_port(padapter, ff_hwaddr, ploopback->txsize, (u8 *)pxmitframe->pxmitbuf);
11786
11787
/* wait for rx pkt */
11788
_rtw_down_sema(&ploopback->sema);
11789
11790
err = pktcmp(padapter, ploopback->txbuf, ploopback->txsize, ploopback->rxbuf, ploopback->rxsize);
11791
if (err == _TRUE)
11792
ok++;
11793
else
11794
fail++;
11795
11796
ploopback->txsize = 0;
11797
_rtw_memset(ploopback->txbuf, 0, 0x8000);
11798
ploopback->rxsize = 0;
11799
_rtw_memset(ploopback->rxbuf, 0, 0x8000);
11800
11801
freeloopbackpkt(padapter, pxmitframe);
11802
pxmitframe = NULL;
11803
11804
flush_signals_thread();
11805
11806
if ((ploopback->bstop == _TRUE) ||
11807
((ploopback->cnt != 0) && (ploopback->cnt == cnt))) {
11808
u32 ok_rate, fail_rate, all;
11809
all = cnt;
11810
ok_rate = (ok * 100) / all;
11811
fail_rate = (fail * 100) / all;
11812
sprintf(ploopback->msg, \
11813
"loopback result: ok=%d%%(%d/%d),error=%d%%(%d/%d)", \
11814
ok_rate, ok, all, fail_rate, fail, all);
11815
break;
11816
}
11817
} while (1);
11818
11819
ploopback->bstop = _TRUE;
11820
11821
thread_exit(NULL);
11822
return 0;
11823
}
11824
11825
static void loopbackTest(PADAPTER padapter, u32 cnt, u32 size, u8 *pmsg)
11826
{
11827
PLOOPBACKDATA ploopback;
11828
u32 len;
11829
s32 err;
11830
11831
11832
ploopback = padapter->ploopback;
11833
11834
if (ploopback) {
11835
if (ploopback->bstop == _FALSE) {
11836
ploopback->bstop = _TRUE;
11837
_rtw_up_sema(&ploopback->sema);
11838
}
11839
len = 0;
11840
do {
11841
len = strlen(ploopback->msg);
11842
if (len)
11843
break;
11844
rtw_msleep_os(1);
11845
} while (1);
11846
_rtw_memcpy(pmsg, ploopback->msg, len + 1);
11847
freeLoopback(padapter);
11848
11849
return;
11850
}
11851
11852
/* disable dynamic algorithm */
11853
rtw_phydm_ability_backup(padapter);
11854
rtw_phydm_func_disable_all(padapter);
11855
11856
/* create pseudo ad-hoc connection */
11857
err = initpseudoadhoc(padapter);
11858
if (err == _FAIL) {
11859
sprintf(pmsg, "loopback FAIL! 1.1 init ad-hoc FAIL!");
11860
return;
11861
}
11862
11863
err = createpseudoadhoc(padapter);
11864
if (err == _FAIL) {
11865
sprintf(pmsg, "loopback FAIL! 1.2 create ad-hoc master FAIL!");
11866
return;
11867
}
11868
11869
err = initLoopback(padapter);
11870
if (err) {
11871
sprintf(pmsg, "loopback FAIL! 2. init FAIL! error code=%d", err);
11872
return;
11873
}
11874
11875
ploopback = padapter->ploopback;
11876
11877
ploopback->bstop = _FALSE;
11878
ploopback->cnt = cnt;
11879
ploopback->size = size;
11880
ploopback->lbkthread = kthread_run(lbk_thread, padapter, "RTW_LBK_THREAD");
11881
if (IS_ERR(padapter->lbkthread)) {
11882
freeLoopback(padapter);
11883
ploopback->lbkthread = NULL;
11884
sprintf(pmsg, "loopback start FAIL! cnt=%d", cnt);
11885
return;
11886
}
11887
11888
sprintf(pmsg, "loopback start! cnt=%d", cnt);
11889
}
11890
#endif /* CONFIG_MAC_LOOPBACK_DRIVER */
11891
11892
static int rtw_test(
11893
struct net_device *dev,
11894
struct iw_request_info *info,
11895
union iwreq_data *wrqu, char *extra)
11896
{
11897
u32 len;
11898
u8 *pbuf, *pch;
11899
char *ptmp;
11900
u8 *delim = ",";
11901
PADAPTER padapter = rtw_netdev_priv(dev);
11902
11903
11904
RTW_INFO("+%s\n", __func__);
11905
len = wrqu->data.length;
11906
11907
pbuf = (u8 *)rtw_zmalloc(len + 1);
11908
if (pbuf == NULL) {
11909
RTW_INFO("%s: no memory!\n", __func__);
11910
return -ENOMEM;
11911
}
11912
11913
if (copy_from_user(pbuf, wrqu->data.pointer, len)) {
11914
rtw_mfree(pbuf, len + 1);
11915
RTW_INFO("%s: copy from user fail!\n", __func__);
11916
return -EFAULT;
11917
}
11918
11919
pbuf[len] = '\0';
11920
11921
RTW_INFO("%s: string=\"%s\"\n", __func__, pbuf);
11922
11923
ptmp = (char *)pbuf;
11924
pch = strsep(&ptmp, delim);
11925
if ((pch == NULL) || (strlen(pch) == 0)) {
11926
rtw_mfree(pbuf, len);
11927
RTW_INFO("%s: parameter error(level 1)!\n", __func__);
11928
return -EFAULT;
11929
}
11930
11931
#ifdef CONFIG_MAC_LOOPBACK_DRIVER
11932
if (strcmp(pch, "loopback") == 0) {
11933
s32 cnt = 0;
11934
u32 size = 64;
11935
11936
pch = strsep(&ptmp, delim);
11937
if ((pch == NULL) || (strlen(pch) == 0)) {
11938
rtw_mfree(pbuf, len);
11939
RTW_INFO("%s: parameter error(level 2)!\n", __func__);
11940
return -EFAULT;
11941
}
11942
11943
sscanf(pch, "%d", &cnt);
11944
RTW_INFO("%s: loopback cnt=%d\n", __func__, cnt);
11945
11946
pch = strsep(&ptmp, delim);
11947
if ((pch == NULL) || (strlen(pch) == 0)) {
11948
rtw_mfree(pbuf, len);
11949
RTW_INFO("%s: parameter error(level 2)!\n", __func__);
11950
return -EFAULT;
11951
}
11952
11953
sscanf(pch, "%d", &size);
11954
RTW_INFO("%s: loopback size=%d\n", __func__, size);
11955
11956
loopbackTest(padapter, cnt, size, extra);
11957
wrqu->data.length = strlen(extra) + 1;
11958
11959
goto free_buf;
11960
}
11961
#endif
11962
11963
11964
#ifdef CONFIG_BT_COEXIST
11965
if (strcmp(pch, "bton") == 0) {
11966
rtw_btcoex_SetManualControl(padapter, _FALSE);
11967
goto free_buf;
11968
} else if (strcmp(pch, "btoff") == 0) {
11969
rtw_btcoex_SetManualControl(padapter, _TRUE);
11970
goto free_buf;
11971
}
11972
#endif
11973
11974
if (strcmp(pch, "h2c") == 0) {
11975
u8 param[8];
11976
u8 count = 0;
11977
u32 tmp;
11978
u8 i;
11979
u32 pos;
11980
u8 ret;
11981
11982
do {
11983
pch = strsep(&ptmp, delim);
11984
if ((pch == NULL) || (strlen(pch) == 0))
11985
break;
11986
11987
sscanf(pch, "%x", &tmp);
11988
param[count++] = (u8)tmp;
11989
} while (count < 8);
11990
11991
if (count == 0) {
11992
rtw_mfree(pbuf, len);
11993
RTW_INFO("%s: parameter error(level 2)!\n", __func__);
11994
return -EFAULT;
11995
}
11996
11997
ret = rtw_test_h2c_cmd(padapter, param, count);
11998
11999
pos = sprintf(extra, "H2C ID=0x%02x content=", param[0]);
12000
for (i = 1; i < count; i++)
12001
pos += sprintf(extra + pos, "%02x,", param[i]);
12002
extra[pos] = 0;
12003
pos--;
12004
pos += sprintf(extra + pos, " %s", ret == _FAIL ? "FAIL" : "OK");
12005
12006
wrqu->data.length = strlen(extra) + 1;
12007
12008
goto free_buf;
12009
}
12010
12011
free_buf:
12012
rtw_mfree(pbuf, len);
12013
return 0;
12014
}
12015
12016
static iw_handler rtw_handlers[] = {
12017
NULL, /* SIOCSIWCOMMIT */
12018
rtw_wx_get_name, /* SIOCGIWNAME */
12019
dummy, /* SIOCSIWNWID */
12020
dummy, /* SIOCGIWNWID */
12021
rtw_wx_set_freq, /* SIOCSIWFREQ */
12022
rtw_wx_get_freq, /* SIOCGIWFREQ */
12023
rtw_wx_set_mode, /* SIOCSIWMODE */
12024
rtw_wx_get_mode, /* SIOCGIWMODE */
12025
dummy, /* SIOCSIWSENS */
12026
rtw_wx_get_sens, /* SIOCGIWSENS */
12027
NULL, /* SIOCSIWRANGE */
12028
rtw_wx_get_range, /* SIOCGIWRANGE */
12029
rtw_wx_set_priv, /* SIOCSIWPRIV */
12030
NULL, /* SIOCGIWPRIV */
12031
NULL, /* SIOCSIWSTATS */
12032
NULL, /* SIOCGIWSTATS */
12033
dummy, /* SIOCSIWSPY */
12034
dummy, /* SIOCGIWSPY */
12035
NULL, /* SIOCGIWTHRSPY */
12036
NULL, /* SIOCWIWTHRSPY */
12037
rtw_wx_set_wap, /* SIOCSIWAP */
12038
rtw_wx_get_wap, /* SIOCGIWAP */
12039
rtw_wx_set_mlme, /* request MLME operation; uses struct iw_mlme */
12040
dummy, /* SIOCGIWAPLIST -- depricated */
12041
rtw_wx_set_scan, /* SIOCSIWSCAN */
12042
rtw_wx_get_scan, /* SIOCGIWSCAN */
12043
rtw_wx_set_essid, /* SIOCSIWESSID */
12044
rtw_wx_get_essid, /* SIOCGIWESSID */
12045
dummy, /* SIOCSIWNICKN */
12046
rtw_wx_get_nick, /* SIOCGIWNICKN */
12047
NULL, /* -- hole -- */
12048
NULL, /* -- hole -- */
12049
rtw_wx_set_rate, /* SIOCSIWRATE */
12050
rtw_wx_get_rate, /* SIOCGIWRATE */
12051
rtw_wx_set_rts, /* SIOCSIWRTS */
12052
rtw_wx_get_rts, /* SIOCGIWRTS */
12053
rtw_wx_set_frag, /* SIOCSIWFRAG */
12054
rtw_wx_get_frag, /* SIOCGIWFRAG */
12055
dummy, /* SIOCSIWTXPOW */
12056
dummy, /* SIOCGIWTXPOW */
12057
dummy, /* SIOCSIWRETRY */
12058
rtw_wx_get_retry, /* SIOCGIWRETRY */
12059
rtw_wx_set_enc, /* SIOCSIWENCODE */
12060
rtw_wx_get_enc, /* SIOCGIWENCODE */
12061
dummy, /* SIOCSIWPOWER */
12062
rtw_wx_get_power, /* SIOCGIWPOWER */
12063
NULL, /*---hole---*/
12064
NULL, /*---hole---*/
12065
rtw_wx_set_gen_ie, /* SIOCSIWGENIE */
12066
NULL, /* SIOCGWGENIE */
12067
rtw_wx_set_auth, /* SIOCSIWAUTH */
12068
NULL, /* SIOCGIWAUTH */
12069
rtw_wx_set_enc_ext, /* SIOCSIWENCODEEXT */
12070
NULL, /* SIOCGIWENCODEEXT */
12071
rtw_wx_set_pmkid, /* SIOCSIWPMKSA */
12072
NULL, /*---hole---*/
12073
};
12074
12075
12076
static const struct iw_priv_args rtw_private_args[] = {
12077
{
12078
SIOCIWFIRSTPRIV + 0x0,
12079
IW_PRIV_TYPE_CHAR | 0x7FF, 0, "write"
12080
},
12081
{
12082
SIOCIWFIRSTPRIV + 0x1,
12083
IW_PRIV_TYPE_CHAR | 0x7FF,
12084
IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "read"
12085
},
12086
{
12087
SIOCIWFIRSTPRIV + 0x2, 0, 0, "driver_ext"
12088
},
12089
{
12090
SIOCIWFIRSTPRIV + 0x3, 0, 0, "mp_ioctl"
12091
},
12092
{
12093
SIOCIWFIRSTPRIV + 0x4,
12094
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "apinfo"
12095
},
12096
{
12097
SIOCIWFIRSTPRIV + 0x5,
12098
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "setpid"
12099
},
12100
{
12101
SIOCIWFIRSTPRIV + 0x6,
12102
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_start"
12103
},
12104
/* for PLATFORM_MT53XX */
12105
{
12106
SIOCIWFIRSTPRIV + 0x7,
12107
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "get_sensitivity"
12108
},
12109
{
12110
SIOCIWFIRSTPRIV + 0x8,
12111
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_prob_req_ie"
12112
},
12113
{
12114
SIOCIWFIRSTPRIV + 0x9,
12115
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wps_assoc_req_ie"
12116
},
12117
12118
/* for RTK_DMP_PLATFORM */
12119
{
12120
SIOCIWFIRSTPRIV + 0xA,
12121
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "channel_plan"
12122
},
12123
12124
{
12125
SIOCIWFIRSTPRIV + 0xB,
12126
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0, "dbg"
12127
},
12128
{
12129
SIOCIWFIRSTPRIV + 0xC,
12130
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "rfw"
12131
},
12132
{
12133
SIOCIWFIRSTPRIV + 0xD,
12134
IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "rfr"
12135
},
12136
#if 0
12137
{
12138
SIOCIWFIRSTPRIV + 0xE, 0, 0, "wowlan_ctrl"
12139
},
12140
#endif
12141
{
12142
SIOCIWFIRSTPRIV + 0x10,
12143
IW_PRIV_TYPE_CHAR | 1024, 0, "p2p_set"
12144
},
12145
{
12146
SIOCIWFIRSTPRIV + 0x11,
12147
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "p2p_get"
12148
},
12149
{
12150
SIOCIWFIRSTPRIV + 0x12, 0, 0, "NULL"
12151
},
12152
{
12153
SIOCIWFIRSTPRIV + 0x13,
12154
IW_PRIV_TYPE_CHAR | 64, IW_PRIV_TYPE_CHAR | 64 , "p2p_get2"
12155
},
12156
{
12157
SIOCIWFIRSTPRIV + 0x14,
12158
IW_PRIV_TYPE_CHAR | 64, 0, "tdls"
12159
},
12160
{
12161
SIOCIWFIRSTPRIV + 0x15,
12162
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "tdls_get"
12163
},
12164
{
12165
SIOCIWFIRSTPRIV + 0x16,
12166
IW_PRIV_TYPE_CHAR | 64, 0, "pm_set"
12167
},
12168
#ifdef CONFIG_RTW_80211K
12169
{
12170
SIOCIWFIRSTPRIV + 0x17,
12171
IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | 1024 , "rrm"
12172
},
12173
#else
12174
{SIOCIWFIRSTPRIV + 0x17, IW_PRIV_TYPE_CHAR | 1024 , 0 , "NULL"},
12175
#endif
12176
{SIOCIWFIRSTPRIV + 0x18, IW_PRIV_TYPE_CHAR | IFNAMSIZ , 0 , "rereg_nd_name"},
12177
#ifdef CONFIG_MP_INCLUDED
12178
{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
12179
{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "NULL"},
12180
#else
12181
{SIOCIWFIRSTPRIV + 0x1A, IW_PRIV_TYPE_CHAR | 1024, 0, "NULL"},
12182
{SIOCIWFIRSTPRIV + 0x1B, IW_PRIV_TYPE_CHAR | 128, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get"},
12183
#endif
12184
{
12185
SIOCIWFIRSTPRIV + 0x1D,
12186
IW_PRIV_TYPE_CHAR | 40, IW_PRIV_TYPE_CHAR | 0x7FF, "test"
12187
},
12188
12189
{ SIOCIWFIRSTPRIV + 0x0E, IW_PRIV_TYPE_CHAR | 1024, 0 , ""}, /* set */
12190
{ SIOCIWFIRSTPRIV + 0x0F, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , ""},/* get
12191
* --- sub-ioctls definitions --- */
12192
12193
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
12194
{ VENDOR_IE_SET, IW_PRIV_TYPE_CHAR | 1024 , 0 , "vendor_ie_set" },
12195
{ VENDOR_IE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "vendor_ie_get" },
12196
#endif
12197
#if defined(CONFIG_RTL8723B)
12198
{ MP_SetBT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setbt" },
12199
{ MP_DISABLE_BT_COEXIST, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_disa_btcoex"},
12200
#endif
12201
#ifdef CONFIG_WOWLAN
12202
{ MP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_mode" },
12203
{ MP_WOW_SET_PATTERN , IW_PRIV_TYPE_CHAR | 1024, 0, "wow_set_pattern" },
12204
#endif
12205
#ifdef CONFIG_AP_WOWLAN
12206
{ MP_AP_WOW_ENABLE , IW_PRIV_TYPE_CHAR | 1024, 0, "ap_wow_mode" }, /* set */
12207
#endif
12208
#ifdef CONFIG_SDIO_INDIRECT_ACCESS
12209
{ MP_SD_IREAD, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iread" },
12210
{ MP_SD_IWRITE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "sd_iwrite" },
12211
#endif
12212
};
12213
12214
12215
static const struct iw_priv_args rtw_mp_private_args[] = {
12216
/* --- sub-ioctls definitions --- */
12217
#ifdef CONFIG_MP_INCLUDED
12218
{ MP_START , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_start" },
12219
{ MP_PHYPARA, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_phypara" },
12220
{ MP_STOP , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_stop" },
12221
{ MP_CHANNEL , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_channel" },
12222
{ MP_CHL_OFFSET , IW_PRIV_TYPE_CHAR | 1024 , IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ch_offset" },
12223
{ MP_BANDWIDTH , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_bandwidth"},
12224
{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12225
{ MP_RESET_STATS , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_reset_stats"},
12226
{ MP_QUERY , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK , "mp_query"},
12227
{ READ_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_reg" },
12228
{ MP_RATE , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rate" },
12229
{ READ_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "read_rf" },
12230
{ MP_PSD , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_psd"},
12231
{ MP_DUMP, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dump" },
12232
{ MP_TXPOWER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_txpower"},
12233
{ MP_ANT_TX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_tx"},
12234
{ MP_ANT_RX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ant_rx"},
12235
{ WRITE_REG , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_reg" },
12236
{ WRITE_RF , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "write_rf" },
12237
{ MP_CTX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ctx"},
12238
{ MP_ARX , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_arx"},
12239
{ MP_THER , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_ther"},
12240
{ EFUSE_SET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_set" },
12241
{ EFUSE_GET, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_get" },
12242
{ MP_PWRTRK , IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrtrk"},
12243
{ MP_QueryDrvStats, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_drvquery" },
12244
{ MP_IOCTL, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_ioctl"},
12245
{ MP_SetRFPathSwh, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_setrfpath" },
12246
{ MP_PwrCtlDM, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrctldm" },
12247
{ MP_GET_TXPOWER_INX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_get_txpower" },
12248
{ MP_GETVER, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_priv_ver" },
12249
{ MP_MON, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_mon" },
12250
{ EFUSE_BT_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_bt_mask" },
12251
{ EFUSE_MASK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_mask" },
12252
{ EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "efuse_file" },
12253
{ MP_TX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_tx" },
12254
{ MP_RX, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_rx" },
12255
{ MP_HW_TX_MODE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_hxtx" },
12256
{ MP_PWRLMT, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrlmt" },
12257
{ MP_PWRBYRATE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_pwrbyrate" },
12258
{ CTA_TEST, IW_PRIV_TYPE_CHAR | 1024, 0, "cta_test"},
12259
{ MP_IQK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_iqk"},
12260
{ MP_LCK, IW_PRIV_TYPE_CHAR | 1024, 0, "mp_lck"},
12261
{ BT_EFUSE_FILE, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "bt_efuse_file" },
12262
{ MP_SWRFPath, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_swrfpath" },
12263
{ MP_LINK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_link" },
12264
{ MP_DPK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk"},
12265
{ MP_DPK_TRK, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "mp_dpk_trk" },
12266
#ifdef CONFIG_RTW_CUSTOMER_STR
12267
{ MP_CUSTOMER_STR, IW_PRIV_TYPE_CHAR | 1024, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_MASK, "customer_str" },
12268
#endif
12269
12270
#endif /* CONFIG_MP_INCLUDED */
12271
};
12272
12273
static iw_handler rtw_private_handler[] = {
12274
rtw_wx_write32, /* 0x00 */
12275
rtw_wx_read32, /* 0x01 */
12276
NULL, /* 0x02 */
12277
#ifdef MP_IOCTL_HDL
12278
rtw_mp_ioctl_hdl, /* 0x03 */
12279
#else
12280
rtw_wx_priv_null,
12281
#endif
12282
/* for MM DTV platform */
12283
rtw_get_ap_info, /* 0x04 */
12284
12285
rtw_set_pid, /* 0x05 */
12286
rtw_wps_start, /* 0x06 */
12287
12288
/* for PLATFORM_MT53XX */
12289
rtw_wx_get_sensitivity, /* 0x07 */
12290
rtw_wx_set_mtk_wps_probe_ie, /* 0x08 */
12291
rtw_wx_set_mtk_wps_ie, /* 0x09 */
12292
12293
/* for RTK_DMP_PLATFORM
12294
* Set Channel depend on the country code */
12295
rtw_wx_set_channel_plan, /* 0x0A */
12296
12297
rtw_dbg_port, /* 0x0B */
12298
rtw_wx_write_rf, /* 0x0C */
12299
rtw_wx_read_rf, /* 0x0D */
12300
12301
rtw_priv_set, /*0x0E*/
12302
rtw_priv_get, /*0x0F*/
12303
12304
rtw_p2p_set, /* 0x10 */
12305
rtw_p2p_get, /* 0x11 */
12306
NULL, /* 0x12 */
12307
rtw_p2p_get2, /* 0x13 */
12308
12309
rtw_tdls, /* 0x14 */
12310
rtw_tdls_get, /* 0x15 */
12311
12312
rtw_pm_set, /* 0x16 */
12313
#ifdef CONFIG_RTW_80211K
12314
rtw_wx_priv_rrm, /* 0x17 */
12315
#else
12316
rtw_wx_priv_null, /* 0x17 */
12317
#endif
12318
rtw_rereg_nd_name, /* 0x18 */
12319
rtw_wx_priv_null, /* 0x19 */
12320
#ifdef CONFIG_MP_INCLUDED
12321
rtw_wx_priv_null, /* 0x1A */
12322
rtw_wx_priv_null, /* 0x1B */
12323
#else
12324
rtw_wx_priv_null, /* 0x1A */
12325
rtw_mp_efuse_get, /* 0x1B */
12326
#endif
12327
NULL, /* 0x1C is reserved for hostapd */
12328
rtw_test, /* 0x1D */
12329
};
12330
12331
#if WIRELESS_EXT >= 17
12332
static struct iw_statistics *rtw_get_wireless_stats(struct net_device *dev)
12333
{
12334
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
12335
struct iw_statistics *piwstats = &padapter->iwstats;
12336
int tmp_level = 0;
12337
int tmp_qual = 0;
12338
int tmp_noise = 0;
12339
12340
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) != _TRUE) {
12341
piwstats->qual.qual = 0;
12342
piwstats->qual.level = 0;
12343
piwstats->qual.noise = 0;
12344
/* RTW_INFO("No link level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); */
12345
} else {
12346
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
12347
tmp_level = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
12348
#else
12349
tmp_level = padapter->recvpriv.signal_strength;
12350
#endif
12351
12352
tmp_qual = padapter->recvpriv.signal_qual;
12353
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
12354
if (IS_NM_ENABLE(padapter)) {
12355
tmp_noise = rtw_noise_measure_curchan(padapter);
12356
#ifndef CONFIG_SIGNAL_DISPLAY_DBM
12357
tmp_noise = translate_dbm_to_percentage(tmp_noise);/*percentage*/
12358
#endif
12359
}
12360
#endif
12361
/* RTW_INFO("level:%d, qual:%d, noise:%d, rssi (%d)\n", tmp_level, tmp_qual, tmp_noise,padapter->recvpriv.rssi); */
12362
12363
piwstats->qual.level = tmp_level;
12364
piwstats->qual.qual = tmp_qual;
12365
piwstats->qual.noise = tmp_noise;
12366
}
12367
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 14))
12368
piwstats->qual.updated = IW_QUAL_ALL_UPDATED ;/* |IW_QUAL_DBM; */
12369
#else
12370
#ifdef RTK_DMP_PLATFORM
12371
/* IW_QUAL_DBM= 0x8, if driver use this flag, wireless extension will show value of dbm. */
12372
/* remove this flag for show percentage 0~100 */
12373
piwstats->qual.updated = 0x07;
12374
#else
12375
piwstats->qual.updated = 0x0f;
12376
#endif
12377
#endif
12378
12379
#ifdef CONFIG_SIGNAL_DISPLAY_DBM
12380
piwstats->qual.updated = piwstats->qual.updated | IW_QUAL_DBM;
12381
#endif
12382
12383
return &padapter->iwstats;
12384
}
12385
#endif
12386
12387
#ifdef CONFIG_WIRELESS_EXT
12388
struct iw_handler_def rtw_handlers_def =
12389
{
12390
.standard = rtw_handlers,
12391
.num_standard = sizeof(rtw_handlers) / sizeof(iw_handler),
12392
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 33)) || defined(CONFIG_WEXT_PRIV)
12393
.private = rtw_private_handler,
12394
.private_args = (struct iw_priv_args *)rtw_private_args,
12395
.num_private = sizeof(rtw_private_handler) / sizeof(iw_handler),
12396
.num_private_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args),
12397
#endif
12398
#if WIRELESS_EXT >= 17
12399
.get_wireless_stats = rtw_get_wireless_stats,
12400
#endif
12401
};
12402
#endif
12403
12404
/* copy from net/wireless/wext.c start
12405
* ----------------------------------------------------------------
12406
*
12407
* Calculate size of private arguments
12408
*/
12409
static const char iw_priv_type_size[] = {
12410
0, /* IW_PRIV_TYPE_NONE */
12411
1, /* IW_PRIV_TYPE_BYTE */
12412
1, /* IW_PRIV_TYPE_CHAR */
12413
0, /* Not defined */
12414
sizeof(__u32), /* IW_PRIV_TYPE_INT */
12415
sizeof(struct iw_freq), /* IW_PRIV_TYPE_FLOAT */
12416
sizeof(struct sockaddr), /* IW_PRIV_TYPE_ADDR */
12417
0, /* Not defined */
12418
};
12419
12420
static int get_priv_size(__u16 args)
12421
{
12422
int num = args & IW_PRIV_SIZE_MASK;
12423
int type = (args & IW_PRIV_TYPE_MASK) >> 12;
12424
12425
return num * iw_priv_type_size[type];
12426
}
12427
/* copy from net/wireless/wext.c end */
12428
12429
12430
static int _rtw_ioctl_wext_private(struct net_device *dev, union iwreq_data *wrq_data)
12431
{
12432
int err = 0;
12433
u8 *input = NULL;
12434
u32 input_len = 0;
12435
const char delim[] = " ";
12436
u8 *output = NULL;
12437
u32 output_len = 0;
12438
u32 count = 0;
12439
u8 *buffer = NULL;
12440
u32 buffer_len = 0;
12441
char *ptr = NULL;
12442
u8 cmdname[17] = {0}; /* IFNAMSIZ+1 */
12443
u32 cmdlen;
12444
s32 len;
12445
u8 *extra = NULL;
12446
u32 extra_size = 0;
12447
12448
s32 k;
12449
const iw_handler *priv; /* Private ioctl */
12450
const struct iw_priv_args *priv_args; /* Private ioctl description */
12451
const struct iw_priv_args *mp_priv_args; /*MP Private ioctl description */
12452
const struct iw_priv_args *sel_priv_args; /*Selected Private ioctl description */
12453
u32 num_priv; /* Number of ioctl */
12454
u32 num_priv_args; /* Number of descriptions */
12455
u32 num_mp_priv_args; /*Number of MP descriptions */
12456
u32 num_sel_priv_args; /*Number of Selected descriptions */
12457
iw_handler handler;
12458
int temp;
12459
int subcmd = 0; /* sub-ioctl index */
12460
int offset = 0; /* Space for sub-ioctl index */
12461
12462
union iwreq_data wdata;
12463
12464
_rtw_memcpy(&wdata, wrq_data, sizeof(wdata));
12465
12466
input_len = wdata.data.length;
12467
if (!input_len)
12468
return -EINVAL;
12469
input = rtw_zmalloc(input_len);
12470
12471
if (input == NULL) {
12472
err = -EOPNOTSUPP;
12473
goto exit;
12474
}
12475
12476
if (copy_from_user(input, wdata.data.pointer, input_len)) {
12477
err = -EFAULT;
12478
goto exit;
12479
}
12480
input[input_len - 1] = '\0';
12481
ptr = input;
12482
len = input_len;
12483
12484
sscanf(ptr, "%16s", cmdname);
12485
cmdlen = strlen(cmdname);
12486
RTW_DBG("%s: cmd=%s\n", __func__, cmdname);
12487
12488
/* skip command string */
12489
if (cmdlen > 0)
12490
cmdlen += 1; /* skip one space */
12491
ptr += cmdlen;
12492
len -= cmdlen;
12493
RTW_DBG("%s: parameters=%s\n", __func__, ptr);
12494
12495
priv = rtw_private_handler;
12496
priv_args = rtw_private_args;
12497
mp_priv_args = rtw_mp_private_args;
12498
num_priv = sizeof(rtw_private_handler) / sizeof(iw_handler);
12499
num_priv_args = sizeof(rtw_private_args) / sizeof(struct iw_priv_args);
12500
num_mp_priv_args = sizeof(rtw_mp_private_args) / sizeof(struct iw_priv_args);
12501
12502
if (num_priv_args == 0) {
12503
err = -EOPNOTSUPP;
12504
goto exit;
12505
}
12506
12507
/* Search the correct ioctl */
12508
k = -1;
12509
sel_priv_args = priv_args;
12510
num_sel_priv_args = num_priv_args;
12511
while
12512
((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12513
;
12514
12515
/* If not found... */
12516
if (k == num_sel_priv_args) {
12517
k = -1;
12518
sel_priv_args = mp_priv_args;
12519
num_sel_priv_args = num_mp_priv_args;
12520
while
12521
((++k < num_sel_priv_args) && strcmp(sel_priv_args[k].name, cmdname))
12522
;
12523
12524
if (k == num_sel_priv_args) {
12525
err = -EOPNOTSUPP;
12526
goto exit;
12527
}
12528
}
12529
12530
/* Watch out for sub-ioctls ! */
12531
if (sel_priv_args[k].cmd < SIOCDEVPRIVATE) {
12532
int j = -1;
12533
12534
/* Find the matching *real* ioctl */
12535
while ((++j < num_priv_args) && ((priv_args[j].name[0] != '\0') ||
12536
(priv_args[j].set_args != sel_priv_args[k].set_args) ||
12537
(priv_args[j].get_args != sel_priv_args[k].get_args)))
12538
;
12539
12540
/* If not found... */
12541
if (j == num_priv_args) {
12542
err = -EINVAL;
12543
goto exit;
12544
}
12545
12546
/* Save sub-ioctl number */
12547
subcmd = sel_priv_args[k].cmd;
12548
/* Reserve one int (simplify alignment issues) */
12549
offset = sizeof(__u32);
12550
/* Use real ioctl definition from now on */
12551
k = j;
12552
}
12553
12554
buffer = rtw_zmalloc(4096);
12555
if (NULL == buffer) {
12556
err = -ENOMEM;
12557
goto exit;
12558
}
12559
12560
if (k >= num_priv_args) {
12561
err = -EINVAL;
12562
goto exit;
12563
}
12564
12565
/* If we have to set some data */
12566
if ((priv_args[k].set_args & IW_PRIV_TYPE_MASK) &&
12567
(priv_args[k].set_args & IW_PRIV_SIZE_MASK)) {
12568
u8 *str;
12569
12570
switch (priv_args[k].set_args & IW_PRIV_TYPE_MASK) {
12571
case IW_PRIV_TYPE_BYTE:
12572
/* Fetch args */
12573
count = 0;
12574
do {
12575
str = strsep(&ptr, delim);
12576
if (NULL == str)
12577
break;
12578
sscanf(str, "%i", &temp);
12579
buffer[count++] = (u8)temp;
12580
} while (1);
12581
buffer_len = count;
12582
12583
/* Number of args to fetch */
12584
wdata.data.length = count;
12585
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12586
wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12587
12588
break;
12589
12590
case IW_PRIV_TYPE_INT:
12591
/* Fetch args */
12592
count = 0;
12593
do {
12594
str = strsep(&ptr, delim);
12595
if (NULL == str)
12596
break;
12597
sscanf(str, "%i", &temp);
12598
((s32 *)buffer)[count++] = (s32)temp;
12599
} while (1);
12600
buffer_len = count * sizeof(s32);
12601
12602
/* Number of args to fetch */
12603
wdata.data.length = count;
12604
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12605
wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12606
12607
break;
12608
12609
case IW_PRIV_TYPE_CHAR:
12610
if (len > 0) {
12611
/* Size of the string to fetch */
12612
wdata.data.length = len;
12613
if (wdata.data.length > (priv_args[k].set_args & IW_PRIV_SIZE_MASK))
12614
wdata.data.length = priv_args[k].set_args & IW_PRIV_SIZE_MASK;
12615
12616
/* Fetch string */
12617
_rtw_memcpy(buffer, ptr, wdata.data.length);
12618
} else {
12619
wdata.data.length = 1;
12620
buffer[0] = '\0';
12621
}
12622
buffer_len = wdata.data.length;
12623
break;
12624
12625
default:
12626
RTW_INFO("%s: Not yet implemented...\n", __func__);
12627
err = -1;
12628
goto exit;
12629
}
12630
12631
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12632
(wdata.data.length != (priv_args[k].set_args & IW_PRIV_SIZE_MASK))) {
12633
RTW_INFO("%s: The command %s needs exactly %d argument(s)...\n",
12634
__func__, cmdname, priv_args[k].set_args & IW_PRIV_SIZE_MASK);
12635
err = -EINVAL;
12636
goto exit;
12637
}
12638
} /* if args to set */
12639
else
12640
wdata.data.length = 0L;
12641
12642
/* Those two tests are important. They define how the driver
12643
* will have to handle the data */
12644
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12645
((get_priv_size(priv_args[k].set_args) + offset) <= IFNAMSIZ)) {
12646
/* First case : all SET args fit within wrq */
12647
if (offset)
12648
wdata.mode = subcmd;
12649
_rtw_memcpy(wdata.name + offset, buffer, IFNAMSIZ - offset);
12650
} else {
12651
if ((priv_args[k].set_args == 0) &&
12652
(priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12653
(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ)) {
12654
/* Second case : no SET args, GET args fit within wrq */
12655
if (offset)
12656
wdata.mode = subcmd;
12657
} else {
12658
/* Third case : args won't fit in wrq, or variable number of args */
12659
if (copy_to_user(wdata.data.pointer, buffer, buffer_len)) {
12660
err = -EFAULT;
12661
goto exit;
12662
}
12663
wdata.data.flags = subcmd;
12664
}
12665
}
12666
12667
rtw_mfree(input, input_len);
12668
input = NULL;
12669
12670
extra_size = 0;
12671
if (IW_IS_SET(priv_args[k].cmd)) {
12672
/* Size of set arguments */
12673
extra_size = get_priv_size(priv_args[k].set_args);
12674
12675
/* Does it fits in iwr ? */
12676
if ((priv_args[k].set_args & IW_PRIV_SIZE_FIXED) &&
12677
((extra_size + offset) <= IFNAMSIZ))
12678
extra_size = 0;
12679
} else {
12680
/* Size of get arguments */
12681
extra_size = get_priv_size(priv_args[k].get_args);
12682
12683
/* Does it fits in iwr ? */
12684
if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12685
(extra_size <= IFNAMSIZ))
12686
extra_size = 0;
12687
}
12688
12689
if (extra_size == 0) {
12690
extra = (u8 *)&wdata;
12691
rtw_mfree(buffer, 4096);
12692
buffer = NULL;
12693
} else
12694
extra = buffer;
12695
12696
handler = priv[priv_args[k].cmd - SIOCIWFIRSTPRIV];
12697
err = handler(dev, NULL, &wdata, extra);
12698
12699
/* If we have to get some data */
12700
if ((priv_args[k].get_args & IW_PRIV_TYPE_MASK) &&
12701
(priv_args[k].get_args & IW_PRIV_SIZE_MASK)) {
12702
int j;
12703
int n = 0; /* number of args */
12704
u8 str[20] = {0};
12705
12706
/* Check where is the returned data */
12707
if ((priv_args[k].get_args & IW_PRIV_SIZE_FIXED) &&
12708
(get_priv_size(priv_args[k].get_args) <= IFNAMSIZ))
12709
n = priv_args[k].get_args & IW_PRIV_SIZE_MASK;
12710
else
12711
n = wdata.data.length;
12712
12713
output = rtw_zmalloc(4096);
12714
if (NULL == output) {
12715
err = -ENOMEM;
12716
goto exit;
12717
}
12718
12719
switch (priv_args[k].get_args & IW_PRIV_TYPE_MASK) {
12720
case IW_PRIV_TYPE_BYTE:
12721
/* Display args */
12722
for (j = 0; j < n; j++) {
12723
sprintf(str, "%d ", extra[j]);
12724
len = strlen(str);
12725
output_len = strlen(output);
12726
if ((output_len + len + 1) > 4096) {
12727
err = -E2BIG;
12728
goto exit;
12729
}
12730
_rtw_memcpy(output + output_len, str, len);
12731
}
12732
break;
12733
12734
case IW_PRIV_TYPE_INT:
12735
/* Display args */
12736
for (j = 0; j < n; j++) {
12737
sprintf(str, "%d ", ((__s32 *)extra)[j]);
12738
len = strlen(str);
12739
output_len = strlen(output);
12740
if ((output_len + len + 1) > 4096) {
12741
err = -E2BIG;
12742
goto exit;
12743
}
12744
_rtw_memcpy(output + output_len, str, len);
12745
}
12746
break;
12747
12748
case IW_PRIV_TYPE_CHAR:
12749
/* Display args */
12750
_rtw_memcpy(output, extra, n);
12751
break;
12752
12753
default:
12754
RTW_INFO("%s: Not yet implemented...\n", __func__);
12755
err = -1;
12756
goto exit;
12757
}
12758
12759
output_len = strlen(output) + 1;
12760
wrq_data->data.length = output_len;
12761
if (copy_to_user(wrq_data->data.pointer, output, output_len)) {
12762
err = -EFAULT;
12763
goto exit;
12764
}
12765
} /* if args to set */
12766
else
12767
wrq_data->data.length = 0;
12768
12769
exit:
12770
if (input)
12771
rtw_mfree(input, input_len);
12772
if (buffer)
12773
rtw_mfree(buffer, 4096);
12774
if (output)
12775
rtw_mfree(output, 4096);
12776
12777
return err;
12778
}
12779
12780
#ifdef CONFIG_COMPAT
12781
static int rtw_ioctl_compat_wext_private(struct net_device *dev, struct ifreq *rq)
12782
{
12783
struct compat_iw_point iwp_compat;
12784
union iwreq_data wrq_data;
12785
int err = 0;
12786
RTW_DBG("%s:...\n", __func__);
12787
if (copy_from_user(&iwp_compat, rq->ifr_ifru.ifru_data, sizeof(struct compat_iw_point)))
12788
return -EFAULT;
12789
12790
wrq_data.data.pointer = compat_ptr(iwp_compat.pointer);
12791
wrq_data.data.length = iwp_compat.length;
12792
wrq_data.data.flags = iwp_compat.flags;
12793
12794
err = _rtw_ioctl_wext_private(dev, &wrq_data);
12795
12796
iwp_compat.pointer = ptr_to_compat(wrq_data.data.pointer);
12797
iwp_compat.length = wrq_data.data.length;
12798
iwp_compat.flags = wrq_data.data.flags;
12799
if (copy_to_user(rq->ifr_ifru.ifru_data, &iwp_compat, sizeof(struct compat_iw_point)))
12800
return -EFAULT;
12801
12802
return err;
12803
}
12804
#endif /* CONFIG_COMPAT */
12805
12806
static int rtw_ioctl_standard_wext_private(struct net_device *dev, struct ifreq *rq)
12807
{
12808
struct iw_point *iwp;
12809
union iwreq_data wrq_data;
12810
int err = 0;
12811
iwp = &wrq_data.data;
12812
RTW_DBG("%s:...\n", __func__);
12813
if (copy_from_user(iwp, rq->ifr_ifru.ifru_data, sizeof(struct iw_point)))
12814
return -EFAULT;
12815
12816
err = _rtw_ioctl_wext_private(dev, &wrq_data);
12817
12818
if (copy_to_user(rq->ifr_ifru.ifru_data, iwp, sizeof(struct iw_point)))
12819
return -EFAULT;
12820
12821
return err;
12822
}
12823
12824
static int rtw_ioctl_wext_private(struct net_device *dev, struct ifreq *rq)
12825
{
12826
#ifdef CONFIG_COMPAT
12827
#if (KERNEL_VERSION(4, 6, 0) > LINUX_VERSION_CODE)
12828
if (is_compat_task())
12829
#else
12830
if (in_compat_syscall())
12831
#endif
12832
return rtw_ioctl_compat_wext_private(dev, rq);
12833
else
12834
#endif /* CONFIG_COMPAT */
12835
return rtw_ioctl_standard_wext_private(dev, rq);
12836
}
12837
12838
int rtw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
12839
{
12840
struct iwreq *wrq = (struct iwreq *)rq;
12841
int ret = 0;
12842
12843
switch (cmd) {
12844
case RTL_IOCTL_WPA_SUPPLICANT:
12845
ret = wpa_supplicant_ioctl(dev, &wrq->u.data);
12846
break;
12847
#ifdef CONFIG_AP_MODE
12848
case RTL_IOCTL_HOSTAPD:
12849
ret = rtw_hostapd_ioctl(dev, &wrq->u.data);
12850
break;
12851
#ifdef CONFIG_WIRELESS_EXT
12852
case SIOCSIWMODE:
12853
ret = rtw_wx_set_mode(dev, NULL, &wrq->u, NULL);
12854
break;
12855
#endif
12856
#endif /* CONFIG_AP_MODE */
12857
case SIOCDEVPRIVATE:
12858
ret = rtw_ioctl_wext_private(dev, rq);
12859
break;
12860
case (SIOCDEVPRIVATE+1):
12861
ret = rtw_android_priv_cmd(dev, rq, cmd);
12862
break;
12863
default:
12864
ret = -EOPNOTSUPP;
12865
break;
12866
}
12867
12868
return ret;
12869
}
12870
12871