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_cfg80211.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_CFG80211_C_
16
17
#include <drv_types.h>
18
#include <hal_data.h>
19
20
#ifdef CONFIG_IOCTL_CFG80211
21
22
#ifndef DBG_RTW_CFG80211_STA_PARAM
23
#define DBG_RTW_CFG80211_STA_PARAM 0
24
#endif
25
26
#ifndef DBG_RTW_CFG80211_MESH_CONF
27
#define DBG_RTW_CFG80211_MESH_CONF 0
28
#endif
29
30
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
31
#define STATION_INFO_INACTIVE_TIME BIT(NL80211_STA_INFO_INACTIVE_TIME)
32
#define STATION_INFO_LLID BIT(NL80211_STA_INFO_LLID)
33
#define STATION_INFO_PLID BIT(NL80211_STA_INFO_PLID)
34
#define STATION_INFO_PLINK_STATE BIT(NL80211_STA_INFO_PLINK_STATE)
35
#define STATION_INFO_SIGNAL BIT(NL80211_STA_INFO_SIGNAL)
36
#define STATION_INFO_TX_BITRATE BIT(NL80211_STA_INFO_TX_BITRATE)
37
#define STATION_INFO_RX_PACKETS BIT(NL80211_STA_INFO_RX_PACKETS)
38
#define STATION_INFO_TX_PACKETS BIT(NL80211_STA_INFO_TX_PACKETS)
39
#define STATION_INFO_TX_FAILED BIT(NL80211_STA_INFO_TX_FAILED)
40
#define STATION_INFO_LOCAL_PM BIT(NL80211_STA_INFO_LOCAL_PM)
41
#define STATION_INFO_PEER_PM BIT(NL80211_STA_INFO_PEER_PM)
42
#define STATION_INFO_NONPEER_PM BIT(NL80211_STA_INFO_NONPEER_PM)
43
#define STATION_INFO_ASSOC_REQ_IES 0
44
#endif /* Linux kernel >= 4.0.0 */
45
46
#include <rtw_wifi_regd.h>
47
48
#define RTW_MAX_MGMT_TX_CNT (8)
49
#define RTW_MAX_MGMT_TX_MS_GAS (500)
50
51
#define RTW_SCAN_IE_LEN_MAX 2304
52
#define RTW_MAX_REMAIN_ON_CHANNEL_DURATION 5000 /* ms */
53
#define RTW_MAX_NUM_PMKIDS 4
54
55
#define RTW_CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */
56
57
#ifdef CONFIG_WAPI_SUPPORT
58
59
#ifndef WLAN_CIPHER_SUITE_SMS4
60
#define WLAN_CIPHER_SUITE_SMS4 0x00147201
61
#endif
62
63
#ifndef WLAN_AKM_SUITE_WAPI_PSK
64
#define WLAN_AKM_SUITE_WAPI_PSK 0x000FAC04
65
#endif
66
67
#ifndef WLAN_AKM_SUITE_WAPI_CERT
68
#define WLAN_AKM_SUITE_WAPI_CERT 0x000FAC12
69
#endif
70
71
#ifndef NL80211_WAPI_VERSION_1
72
#define NL80211_WAPI_VERSION_1 (1 << 2)
73
#endif
74
75
#endif /* CONFIG_WAPI_SUPPORT */
76
77
#if (LINUX_VERSION_CODE <= KERNEL_VERSION(4, 11, 12))
78
#ifdef CONFIG_RTW_80211R
79
#define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
80
#define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
81
#endif
82
#endif
83
84
/*
85
* In the current design of Wi-Fi driver, it will return success to the system (e.g. supplicant)
86
* when Wi-Fi driver decides to abort the scan request in the scan flow by default.
87
* Defining this flag makes Wi-Fi driver to return -EBUSY to the system if Wi-Fi driver is too busy to do the scan.
88
*/
89
#ifndef CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY
90
#define CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY 0
91
#endif
92
93
static const u32 rtw_cipher_suites[] = {
94
WLAN_CIPHER_SUITE_WEP40,
95
WLAN_CIPHER_SUITE_WEP104,
96
WLAN_CIPHER_SUITE_TKIP,
97
WLAN_CIPHER_SUITE_CCMP,
98
#ifdef CONFIG_WAPI_SUPPORT
99
WLAN_CIPHER_SUITE_SMS4,
100
#endif /* CONFIG_WAPI_SUPPORT */
101
#ifdef CONFIG_IEEE80211W
102
WLAN_CIPHER_SUITE_AES_CMAC,
103
#endif /* CONFIG_IEEE80211W */
104
};
105
106
#define RATETAB_ENT(_rate, _rateid, _flags) \
107
{ \
108
.bitrate = (_rate), \
109
.hw_value = (_rateid), \
110
.flags = (_flags), \
111
}
112
113
#define CHAN2G(_channel, _freq, _flags) { \
114
.band = NL80211_BAND_2GHZ, \
115
.center_freq = (_freq), \
116
.hw_value = (_channel), \
117
.flags = (_flags), \
118
.max_antenna_gain = 0, \
119
.max_power = 30, \
120
}
121
122
#define CHAN5G(_channel, _flags) { \
123
.band = NL80211_BAND_5GHZ, \
124
.center_freq = 5000 + (5 * (_channel)), \
125
.hw_value = (_channel), \
126
.flags = (_flags), \
127
.max_antenna_gain = 0, \
128
.max_power = 30, \
129
}
130
131
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
132
/* if wowlan is not supported, kernel generate a disconnect at each suspend
133
* cf: /net/wireless/sysfs.c, so register a stub wowlan.
134
* Moreover wowlan has to be enabled via a the nl80211_set_wowlan callback.
135
* (from user space, e.g. iw phy0 wowlan enable)
136
*/
137
static const struct wiphy_wowlan_support wowlan_stub = {
138
.flags = WIPHY_WOWLAN_ANY,
139
.n_patterns = 0,
140
.pattern_max_len = 0,
141
.pattern_min_len = 0,
142
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
143
.max_pkt_offset = 0,
144
#endif
145
};
146
#endif
147
148
static struct ieee80211_rate rtw_rates[] = {
149
RATETAB_ENT(10, 0x1, 0),
150
RATETAB_ENT(20, 0x2, 0),
151
RATETAB_ENT(55, 0x4, 0),
152
RATETAB_ENT(110, 0x8, 0),
153
RATETAB_ENT(60, 0x10, 0),
154
RATETAB_ENT(90, 0x20, 0),
155
RATETAB_ENT(120, 0x40, 0),
156
RATETAB_ENT(180, 0x80, 0),
157
RATETAB_ENT(240, 0x100, 0),
158
RATETAB_ENT(360, 0x200, 0),
159
RATETAB_ENT(480, 0x400, 0),
160
RATETAB_ENT(540, 0x800, 0),
161
};
162
163
#define rtw_a_rates (rtw_rates + 4)
164
#define RTW_A_RATES_NUM 8
165
#define rtw_g_rates (rtw_rates + 0)
166
#define RTW_G_RATES_NUM 12
167
168
/* from center_ch_2g */
169
static struct ieee80211_channel rtw_2ghz_channels[MAX_CHANNEL_NUM_2G] = {
170
CHAN2G(1, 2412, 0),
171
CHAN2G(2, 2417, 0),
172
CHAN2G(3, 2422, 0),
173
CHAN2G(4, 2427, 0),
174
CHAN2G(5, 2432, 0),
175
CHAN2G(6, 2437, 0),
176
CHAN2G(7, 2442, 0),
177
CHAN2G(8, 2447, 0),
178
CHAN2G(9, 2452, 0),
179
CHAN2G(10, 2457, 0),
180
CHAN2G(11, 2462, 0),
181
CHAN2G(12, 2467, 0),
182
CHAN2G(13, 2472, 0),
183
CHAN2G(14, 2484, 0),
184
};
185
186
/* from center_ch_5g_20m */
187
static struct ieee80211_channel rtw_5ghz_a_channels[MAX_CHANNEL_NUM_5G] = {
188
CHAN5G(36, 0), CHAN5G(40, 0), CHAN5G(44, 0), CHAN5G(48, 0),
189
190
CHAN5G(52, 0), CHAN5G(56, 0), CHAN5G(60, 0), CHAN5G(64, 0),
191
192
CHAN5G(100, 0), CHAN5G(104, 0), CHAN5G(108, 0), CHAN5G(112, 0),
193
CHAN5G(116, 0), CHAN5G(120, 0), CHAN5G(124, 0), CHAN5G(128, 0),
194
CHAN5G(132, 0), CHAN5G(136, 0), CHAN5G(140, 0), CHAN5G(144, 0),
195
196
CHAN5G(149, 0), CHAN5G(153, 0), CHAN5G(157, 0), CHAN5G(161, 0),
197
CHAN5G(165, 0), CHAN5G(169, 0), CHAN5G(173, 0), CHAN5G(177, 0),
198
};
199
200
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
201
static u8 rtw_chbw_to_cfg80211_chan_def(struct wiphy *wiphy, struct cfg80211_chan_def *chdef, u8 ch, u8 bw, u8 offset, u8 ht)
202
{
203
int freq, cfreq;
204
struct ieee80211_channel *chan;
205
u8 ret = _FAIL;
206
207
freq = rtw_ch2freq(ch);
208
if (!freq)
209
goto exit;
210
211
cfreq = rtw_get_center_ch(ch, bw, offset);
212
if (!cfreq)
213
goto exit;
214
cfreq = rtw_ch2freq(cfreq);
215
if (!cfreq)
216
goto exit;
217
218
chan = ieee80211_get_channel(wiphy, freq);
219
if (!chan)
220
goto exit;
221
222
if (bw == CHANNEL_WIDTH_20)
223
chdef->width = ht ? NL80211_CHAN_WIDTH_20 : NL80211_CHAN_WIDTH_20_NOHT;
224
else if (bw == CHANNEL_WIDTH_40)
225
chdef->width = NL80211_CHAN_WIDTH_40;
226
else if (bw == CHANNEL_WIDTH_80)
227
chdef->width = NL80211_CHAN_WIDTH_80;
228
else if (bw == CHANNEL_WIDTH_160)
229
chdef->width = NL80211_CHAN_WIDTH_160;
230
else {
231
rtw_warn_on(1);
232
goto exit;
233
}
234
235
chdef->chan = chan;
236
chdef->center_freq1 = cfreq;
237
chdef->center_freq2 = 0;
238
239
ret = _SUCCESS;
240
241
exit:
242
return ret;
243
}
244
245
#ifdef CONFIG_RTW_MESH
246
static const char *nl80211_chan_width_str(enum nl80211_chan_width cwidth)
247
{
248
switch (cwidth) {
249
case NL80211_CHAN_WIDTH_20_NOHT:
250
return "20_NOHT";
251
case NL80211_CHAN_WIDTH_20:
252
return "20";
253
case NL80211_CHAN_WIDTH_40:
254
return "40";
255
case NL80211_CHAN_WIDTH_80:
256
return "80";
257
case NL80211_CHAN_WIDTH_80P80:
258
return "80+80";
259
case NL80211_CHAN_WIDTH_160:
260
return "160";
261
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
262
case NL80211_CHAN_WIDTH_5:
263
return "5";
264
case NL80211_CHAN_WIDTH_10:
265
return "10";
266
#endif
267
default:
268
return "INVALID";
269
};
270
}
271
272
static void rtw_get_chbw_from_cfg80211_chan_def(struct cfg80211_chan_def *chdef, u8 *ht, u8 *ch, u8 *bw, u8 *offset)
273
{
274
int pri_freq;
275
struct ieee80211_channel *chan = chdef->chan;
276
277
pri_freq = rtw_ch2freq(chan->hw_value);
278
if (!pri_freq) {
279
RTW_INFO("invalid channel:%d\n", chan->hw_value);
280
rtw_warn_on(1);
281
*ch = 0;
282
return;
283
}
284
285
switch (chdef->width) {
286
case NL80211_CHAN_WIDTH_20_NOHT:
287
*ht = 0;
288
*bw = CHANNEL_WIDTH_20;
289
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
290
*ch = chan->hw_value;
291
break;
292
case NL80211_CHAN_WIDTH_20:
293
*ht = 1;
294
*bw = CHANNEL_WIDTH_20;
295
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
296
*ch = chan->hw_value;
297
break;
298
case NL80211_CHAN_WIDTH_40:
299
*ht = 1;
300
*bw = CHANNEL_WIDTH_40;
301
*offset = pri_freq > chdef->center_freq1 ? HAL_PRIME_CHNL_OFFSET_UPPER : HAL_PRIME_CHNL_OFFSET_LOWER;
302
if (rtw_get_offset_by_chbw(chan->hw_value, *bw, offset))
303
*ch = chan->hw_value;
304
break;
305
case NL80211_CHAN_WIDTH_80:
306
*ht = 1;
307
*bw = CHANNEL_WIDTH_80;
308
if (rtw_get_offset_by_chbw(chan->hw_value, *bw, offset))
309
*ch = chan->hw_value;
310
break;
311
case NL80211_CHAN_WIDTH_160:
312
*ht = 1;
313
*bw = CHANNEL_WIDTH_160;
314
if (rtw_get_offset_by_chbw(chan->hw_value, *bw, offset))
315
*ch = chan->hw_value;
316
break;
317
case NL80211_CHAN_WIDTH_80P80:
318
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
319
case NL80211_CHAN_WIDTH_5:
320
case NL80211_CHAN_WIDTH_10:
321
#endif
322
default:
323
*ht = 0;
324
*bw = CHANNEL_WIDTH_20;
325
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
326
RTW_INFO("unsupported cwidth:%s\n", nl80211_chan_width_str(chdef->width));
327
rtw_warn_on(1);
328
};
329
}
330
#endif /* CONFIG_RTW_MESH */
331
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
332
static const char *nl80211_channel_type_str(enum nl80211_channel_type ctype)
333
{
334
switch (ctype) {
335
case NL80211_CHAN_NO_HT:
336
return "NO_HT";
337
case NL80211_CHAN_HT20:
338
return "HT20";
339
case NL80211_CHAN_HT40MINUS:
340
return "HT40-";
341
case NL80211_CHAN_HT40PLUS:
342
return "HT40+";
343
default:
344
return "INVALID";
345
};
346
}
347
348
static enum nl80211_channel_type rtw_chbw_to_nl80211_channel_type(u8 ch, u8 bw, u8 offset, u8 ht)
349
{
350
rtw_warn_on(!ht && (bw >= CHANNEL_WIDTH_40 || offset != HAL_PRIME_CHNL_OFFSET_DONT_CARE));
351
352
if (!ht)
353
return NL80211_CHAN_NO_HT;
354
if (bw >= CHANNEL_WIDTH_40) {
355
if (offset == HAL_PRIME_CHNL_OFFSET_UPPER)
356
return NL80211_CHAN_HT40MINUS;
357
else if (offset == HAL_PRIME_CHNL_OFFSET_LOWER)
358
return NL80211_CHAN_HT40PLUS;
359
else
360
rtw_warn_on(1);
361
}
362
return NL80211_CHAN_HT20;
363
}
364
365
static void rtw_get_chbw_from_nl80211_channel_type(struct ieee80211_channel *chan, enum nl80211_channel_type ctype, u8 *ht, u8 *ch, u8 *bw, u8 *offset)
366
{
367
int pri_freq;
368
369
pri_freq = rtw_ch2freq(chan->hw_value);
370
if (!pri_freq) {
371
RTW_INFO("invalid channel:%d\n", chan->hw_value);
372
rtw_warn_on(1);
373
*ch = 0;
374
return;
375
}
376
*ch = chan->hw_value;
377
378
switch (ctype) {
379
case NL80211_CHAN_NO_HT:
380
*ht = 0;
381
*bw = CHANNEL_WIDTH_20;
382
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
383
break;
384
case NL80211_CHAN_HT20:
385
*ht = 1;
386
*bw = CHANNEL_WIDTH_20;
387
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
388
break;
389
case NL80211_CHAN_HT40MINUS:
390
*ht = 1;
391
*bw = CHANNEL_WIDTH_40;
392
*offset = HAL_PRIME_CHNL_OFFSET_UPPER;
393
break;
394
case NL80211_CHAN_HT40PLUS:
395
*ht = 1;
396
*bw = CHANNEL_WIDTH_40;
397
*offset = HAL_PRIME_CHNL_OFFSET_LOWER;
398
break;
399
default:
400
*ht = 0;
401
*bw = CHANNEL_WIDTH_20;
402
*offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
403
RTW_INFO("unsupported ctype:%s\n", nl80211_channel_type_str(ctype));
404
rtw_warn_on(1);
405
};
406
}
407
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) */
408
409
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
410
u8 rtw_cfg80211_ch_switch_notify(_adapter *adapter, u8 ch, u8 bw, u8 offset,
411
u8 ht, bool started)
412
{
413
struct wiphy *wiphy = adapter_to_wiphy(adapter);
414
u8 ret = _SUCCESS;
415
416
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
417
struct cfg80211_chan_def chdef = {};
418
419
ret = rtw_chbw_to_cfg80211_chan_def(wiphy, &chdef, ch, bw, offset, ht);
420
if (ret != _SUCCESS)
421
goto exit;
422
423
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
424
if (started) {
425
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0))
426
427
/* --- cfg80211_ch_switch_started_notfiy() ---
428
* A new parameter, bool quiet, is added from Linux kernel v5.11,
429
* to see if block-tx was requested by the AP. since currently,
430
* the API is used for station before connected in rtw_chk_start_clnt_join()
431
* the quiet is set to false here first. May need to refine it if
432
* called by others with block-tx.
433
*/
434
435
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
436
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
437
cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, 0, false, 0);
438
#else
439
cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, 0, false);
440
#endif
441
#else
442
cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0, false);
443
#endif
444
#else
445
cfg80211_ch_switch_started_notify(adapter->pnetdev, &chdef, 0);
446
#endif
447
goto exit;
448
}
449
#endif
450
//
451
// if (!rtw_cfg80211_allow_ch_switch_notify(adapter))
452
// goto exit;
453
454
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2))
455
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 3, 0))
456
cfg80211_ch_switch_notify(adapter->pnetdev, &chdef, 0, 0);
457
#else
458
cfg80211_ch_switch_notify(adapter->pnetdev, &chdef, 0);
459
#endif
460
#else
461
cfg80211_ch_switch_notify(adapter->pnetdev, &chdef);
462
#endif
463
464
#else
465
int freq = rtw_ch2freq(ch);
466
enum nl80211_channel_type ctype;
467
468
if (!freq) {
469
ret = _FAIL;
470
goto exit;
471
}
472
473
ctype = rtw_chbw_to_nl80211_channel_type(ch, bw, offset, ht);
474
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2))
475
cfg80211_ch_switch_notify(adapter->pnetdev, freq, ctype, 0);
476
#else
477
cfg80211_ch_switch_notify(adapter->pnetdev, freq, ctype);
478
#endif
479
#endif
480
481
exit:
482
return ret;
483
}
484
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) */
485
486
void rtw_2g_channels_init(struct ieee80211_channel *channels)
487
{
488
_rtw_memcpy((void *)channels, (void *)rtw_2ghz_channels, sizeof(rtw_2ghz_channels));
489
}
490
491
void rtw_5g_channels_init(struct ieee80211_channel *channels)
492
{
493
_rtw_memcpy((void *)channels, (void *)rtw_5ghz_a_channels, sizeof(rtw_5ghz_a_channels));
494
}
495
496
void rtw_2g_rates_init(struct ieee80211_rate *rates)
497
{
498
_rtw_memcpy(rates, rtw_g_rates,
499
sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM
500
);
501
}
502
503
void rtw_5g_rates_init(struct ieee80211_rate *rates)
504
{
505
_rtw_memcpy(rates, rtw_a_rates,
506
sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM
507
);
508
}
509
510
struct ieee80211_supported_band *rtw_spt_band_alloc(BAND_TYPE band)
511
{
512
struct ieee80211_supported_band *spt_band = NULL;
513
int n_channels, n_bitrates;
514
515
if (band == BAND_ON_2_4G) {
516
n_channels = MAX_CHANNEL_NUM_2G;
517
n_bitrates = RTW_G_RATES_NUM;
518
} else if (band == BAND_ON_5G) {
519
n_channels = MAX_CHANNEL_NUM_5G;
520
n_bitrates = RTW_A_RATES_NUM;
521
} else
522
goto exit;
523
524
spt_band = (struct ieee80211_supported_band *)rtw_zmalloc(
525
sizeof(struct ieee80211_supported_band)
526
+ sizeof(struct ieee80211_channel) * n_channels
527
+ sizeof(struct ieee80211_rate) * n_bitrates
528
);
529
if (!spt_band)
530
goto exit;
531
532
spt_band->channels = (struct ieee80211_channel *)(((u8 *)spt_band) + sizeof(struct ieee80211_supported_band));
533
spt_band->bitrates = (struct ieee80211_rate *)(((u8 *)spt_band->channels) + sizeof(struct ieee80211_channel) * n_channels);
534
spt_band->band = rtw_band_to_nl80211_band(band);
535
spt_band->n_channels = n_channels;
536
spt_band->n_bitrates = n_bitrates;
537
538
if (band == BAND_ON_2_4G) {
539
rtw_2g_channels_init(spt_band->channels);
540
rtw_2g_rates_init(spt_band->bitrates);
541
} else if (band == BAND_ON_5G) {
542
rtw_5g_channels_init(spt_band->channels);
543
rtw_5g_rates_init(spt_band->bitrates);
544
}
545
546
/* spt_band.ht_cap */
547
548
exit:
549
550
return spt_band;
551
}
552
553
void rtw_spt_band_free(struct ieee80211_supported_band *spt_band)
554
{
555
u32 size = 0;
556
557
if (!spt_band)
558
return;
559
560
if (spt_band->band == NL80211_BAND_2GHZ) {
561
size = sizeof(struct ieee80211_supported_band)
562
+ sizeof(struct ieee80211_channel) * MAX_CHANNEL_NUM_2G
563
+ sizeof(struct ieee80211_rate) * RTW_G_RATES_NUM;
564
} else if (spt_band->band == NL80211_BAND_5GHZ) {
565
size = sizeof(struct ieee80211_supported_band)
566
+ sizeof(struct ieee80211_channel) * MAX_CHANNEL_NUM_5G
567
+ sizeof(struct ieee80211_rate) * RTW_A_RATES_NUM;
568
} else {
569
570
}
571
rtw_mfree((u8 *)spt_band, size);
572
}
573
574
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
575
static const struct ieee80211_txrx_stypes
576
rtw_cfg80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = {
577
[NL80211_IFTYPE_ADHOC] = {
578
.tx = 0xffff,
579
.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
580
},
581
[NL80211_IFTYPE_STATION] = {
582
.tx = 0xffff,
583
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
584
BIT(IEEE80211_STYPE_AUTH >> 4) |
585
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
586
},
587
[NL80211_IFTYPE_AP] = {
588
.tx = 0xffff,
589
.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
590
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
591
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
592
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
593
BIT(IEEE80211_STYPE_AUTH >> 4) |
594
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
595
BIT(IEEE80211_STYPE_ACTION >> 4)
596
},
597
[NL80211_IFTYPE_AP_VLAN] = {
598
/* copy AP */
599
.tx = 0xffff,
600
.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
601
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
602
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
603
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
604
BIT(IEEE80211_STYPE_AUTH >> 4) |
605
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
606
BIT(IEEE80211_STYPE_ACTION >> 4)
607
},
608
[NL80211_IFTYPE_P2P_CLIENT] = {
609
.tx = 0xffff,
610
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
611
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
612
},
613
[NL80211_IFTYPE_P2P_GO] = {
614
.tx = 0xffff,
615
.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
616
BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
617
BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
618
BIT(IEEE80211_STYPE_DISASSOC >> 4) |
619
BIT(IEEE80211_STYPE_AUTH >> 4) |
620
BIT(IEEE80211_STYPE_DEAUTH >> 4) |
621
BIT(IEEE80211_STYPE_ACTION >> 4)
622
},
623
#if defined(RTW_DEDICATED_P2P_DEVICE)
624
[NL80211_IFTYPE_P2P_DEVICE] = {
625
.tx = 0xffff,
626
.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
627
BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
628
},
629
#endif
630
#if defined(CONFIG_RTW_MESH)
631
[NL80211_IFTYPE_MESH_POINT] = {
632
.tx = 0xffff,
633
.rx = BIT(IEEE80211_STYPE_ACTION >> 4)
634
| BIT(IEEE80211_STYPE_AUTH >> 4)
635
},
636
#endif
637
638
};
639
#endif
640
641
NDIS_802_11_NETWORK_INFRASTRUCTURE nl80211_iftype_to_rtw_network_type(enum nl80211_iftype type)
642
{
643
switch (type) {
644
case NL80211_IFTYPE_ADHOC:
645
return Ndis802_11IBSS;
646
647
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
648
case NL80211_IFTYPE_P2P_CLIENT:
649
#endif
650
case NL80211_IFTYPE_STATION:
651
return Ndis802_11Infrastructure;
652
653
#ifdef CONFIG_AP_MODE
654
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
655
case NL80211_IFTYPE_P2P_GO:
656
#endif
657
case NL80211_IFTYPE_AP:
658
return Ndis802_11APMode;
659
#endif
660
661
#ifdef CONFIG_RTW_MESH
662
case NL80211_IFTYPE_MESH_POINT:
663
return Ndis802_11_mesh;
664
#endif
665
666
case NL80211_IFTYPE_MONITOR:
667
return Ndis802_11Monitor;
668
669
default:
670
return Ndis802_11InfrastructureMax;
671
}
672
}
673
674
u32 nl80211_iftype_to_rtw_mlme_state(enum nl80211_iftype type)
675
{
676
switch (type) {
677
case NL80211_IFTYPE_ADHOC:
678
return WIFI_ADHOC_STATE;
679
680
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
681
case NL80211_IFTYPE_P2P_CLIENT:
682
#endif
683
case NL80211_IFTYPE_STATION:
684
return WIFI_STATION_STATE;
685
686
#ifdef CONFIG_AP_MODE
687
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
688
case NL80211_IFTYPE_P2P_GO:
689
#endif
690
case NL80211_IFTYPE_AP:
691
return WIFI_AP_STATE;
692
#endif
693
694
#ifdef CONFIG_RTW_MESH
695
case NL80211_IFTYPE_MESH_POINT:
696
return WIFI_MESH_STATE;
697
#endif
698
699
case NL80211_IFTYPE_MONITOR:
700
return WIFI_MONITOR_STATE;
701
702
default:
703
return WIFI_NULL_STATE;
704
}
705
}
706
707
static int rtw_cfg80211_sync_iftype(_adapter *adapter)
708
{
709
struct wireless_dev *rtw_wdev = adapter->rtw_wdev;
710
711
if (!(nl80211_iftype_to_rtw_mlme_state(rtw_wdev->iftype) & MLME_STATE(adapter))) {
712
/* iftype and mlme state is not syc */
713
NDIS_802_11_NETWORK_INFRASTRUCTURE network_type;
714
715
network_type = nl80211_iftype_to_rtw_network_type(rtw_wdev->iftype);
716
if (network_type != Ndis802_11InfrastructureMax) {
717
if (rtw_pwr_wakeup(adapter) == _FAIL) {
718
RTW_WARN(FUNC_ADPT_FMT" call rtw_pwr_wakeup fail\n", FUNC_ADPT_ARG(adapter));
719
return _FAIL;
720
}
721
722
rtw_set_802_11_infrastructure_mode(adapter, network_type, 0);
723
rtw_setopmode_cmd(adapter, network_type, RTW_CMDF_WAIT_ACK);
724
} else {
725
rtw_warn_on(1);
726
RTW_WARN(FUNC_ADPT_FMT" iftype:%u is not support\n", FUNC_ADPT_ARG(adapter), rtw_wdev->iftype);
727
return _FAIL;
728
}
729
}
730
731
return _SUCCESS;
732
}
733
734
static u64 rtw_get_systime_us(void)
735
{
736
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 20, 0))
737
return ktime_to_us(ktime_get_boottime());
738
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 39))
739
struct timespec ts;
740
get_monotonic_boottime(&ts);
741
return ((u64)ts.tv_sec * 1000000) + ts.tv_nsec / 1000;
742
#else
743
struct timeval tv;
744
do_gettimeofday(&tv);
745
return ((u64)tv.tv_sec * 1000000) + tv.tv_usec;
746
#endif
747
}
748
749
/* Try to remove non target BSS's SR to reduce PBC overlap rate */
750
static int rtw_cfg80211_clear_wps_sr_of_non_target_bss(_adapter *padapter, struct wlan_network *pnetwork, struct cfg80211_ssid *req_ssid)
751
{
752
int ret = 0;
753
u8 *psr = NULL, sr = 0;
754
NDIS_802_11_SSID *pssid = &pnetwork->network.Ssid;
755
u32 wpsielen = 0;
756
u8 *wpsie = NULL;
757
758
if (pssid->SsidLength == req_ssid->ssid_len
759
&& _rtw_memcmp(pssid->Ssid, req_ssid->ssid, req_ssid->ssid_len) == _TRUE)
760
goto exit;
761
762
wpsie = rtw_get_wps_ie(pnetwork->network.IEs + _FIXED_IE_LENGTH_
763
, pnetwork->network.IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
764
if (wpsie && wpsielen > 0)
765
psr = rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_SELECTED_REGISTRAR, &sr, NULL);
766
767
if (psr && sr) {
768
if (0)
769
RTW_INFO("clear sr of non target bss:%s("MAC_FMT")\n"
770
, pssid->Ssid, MAC_ARG(pnetwork->network.MacAddress));
771
*psr = 0; /* clear sr */
772
ret = 1;
773
}
774
775
exit:
776
return ret;
777
}
778
779
#define MAX_BSSINFO_LEN 1000
780
struct cfg80211_bss *rtw_cfg80211_inform_bss(_adapter *padapter, struct wlan_network *pnetwork)
781
{
782
struct ieee80211_channel *notify_channel;
783
struct cfg80211_bss *bss = NULL;
784
/* struct ieee80211_supported_band *band; */
785
u16 channel;
786
u32 freq;
787
u64 notify_timestamp;
788
u16 notify_capability;
789
u16 notify_interval;
790
u8 *notify_ie;
791
size_t notify_ielen;
792
s32 notify_signal;
793
/* u8 buf[MAX_BSSINFO_LEN]; */
794
795
u8 *pbuf;
796
size_t buf_size = MAX_BSSINFO_LEN;
797
size_t len, bssinf_len = 0;
798
struct rtw_ieee80211_hdr *pwlanhdr;
799
unsigned short *fctrl;
800
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
801
802
struct wireless_dev *wdev = padapter->rtw_wdev;
803
struct wiphy *wiphy = wdev->wiphy;
804
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
805
806
pbuf = rtw_zmalloc(buf_size);
807
if (pbuf == NULL) {
808
RTW_INFO("%s pbuf allocate failed !!\n", __FUNCTION__);
809
return bss;
810
}
811
812
/* RTW_INFO("%s\n", __func__); */
813
814
bssinf_len = pnetwork->network.IELength + sizeof(struct rtw_ieee80211_hdr_3addr);
815
if (bssinf_len > buf_size) {
816
RTW_INFO("%s IE Length too long > %zu byte\n", __FUNCTION__, buf_size);
817
goto exit;
818
}
819
820
#ifndef CONFIG_WAPI_SUPPORT
821
{
822
u16 wapi_len = 0;
823
824
if (rtw_get_wapi_ie(pnetwork->network.IEs, pnetwork->network.IELength, NULL, &wapi_len) > 0) {
825
if (wapi_len > 0) {
826
RTW_INFO("%s, no support wapi!\n", __FUNCTION__);
827
goto exit;
828
}
829
}
830
}
831
#endif /* !CONFIG_WAPI_SUPPORT */
832
833
channel = pnetwork->network.Configuration.DSConfig;
834
freq = rtw_ch2freq(channel);
835
notify_channel = ieee80211_get_channel(wiphy, freq);
836
837
if (0)
838
notify_timestamp = le64_to_cpu(*(u64 *)rtw_get_timestampe_from_ie(pnetwork->network.IEs));
839
else
840
notify_timestamp = rtw_get_systime_us();
841
842
notify_interval = le16_to_cpu(*(u16 *)rtw_get_beacon_interval_from_ie(pnetwork->network.IEs));
843
notify_capability = le16_to_cpu(*(u16 *)rtw_get_capability_from_ie(pnetwork->network.IEs));
844
845
notify_ie = pnetwork->network.IEs + _FIXED_IE_LENGTH_;
846
notify_ielen = pnetwork->network.IELength - _FIXED_IE_LENGTH_;
847
848
/* We've set wiphy's signal_type as CFG80211_SIGNAL_TYPE_MBM: signal strength in mBm (100*dBm) */
849
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
850
is_same_network(&pmlmepriv->cur_network.network, &pnetwork->network, 0)) {
851
notify_signal = 100 * translate_percentage_to_dbm(padapter->recvpriv.signal_strength); /* dbm */
852
} else {
853
notify_signal = 100 * translate_percentage_to_dbm(pnetwork->network.PhyInfo.SignalStrength); /* dbm */
854
}
855
856
#if 0
857
RTW_INFO("bssid: "MAC_FMT"\n", MAC_ARG(pnetwork->network.MacAddress));
858
RTW_INFO("Channel: %d(%d)\n", channel, freq);
859
RTW_INFO("Capability: %X\n", notify_capability);
860
RTW_INFO("Beacon interval: %d\n", notify_interval);
861
RTW_INFO("Signal: %d\n", notify_signal);
862
RTW_INFO("notify_timestamp: %llu\n", notify_timestamp);
863
#endif
864
865
/* pbuf = buf; */
866
867
pwlanhdr = (struct rtw_ieee80211_hdr *)pbuf;
868
fctrl = &(pwlanhdr->frame_ctl);
869
*(fctrl) = 0;
870
871
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
872
/* pmlmeext->mgnt_seq++; */
873
874
if (pnetwork->network.Reserved[0] == BSS_TYPE_BCN) { /* WIFI_BEACON */
875
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
876
set_frame_sub_type(pbuf, WIFI_BEACON);
877
} else {
878
_rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
879
set_frame_sub_type(pbuf, WIFI_PROBERSP);
880
}
881
882
_rtw_memcpy(pwlanhdr->addr2, pnetwork->network.MacAddress, ETH_ALEN);
883
_rtw_memcpy(pwlanhdr->addr3, pnetwork->network.MacAddress, ETH_ALEN);
884
885
886
/* pbuf += sizeof(struct rtw_ieee80211_hdr_3addr); */
887
len = sizeof(struct rtw_ieee80211_hdr_3addr);
888
_rtw_memcpy((pbuf + len), pnetwork->network.IEs, pnetwork->network.IELength);
889
*((u64 *)(pbuf + len)) = cpu_to_le64(notify_timestamp);
890
891
len += pnetwork->network.IELength;
892
893
#if defined(CONFIG_P2P) && 0
894
if(rtw_get_p2p_ie(pnetwork->network.IEs+12, pnetwork->network.IELength-12, NULL, NULL))
895
RTW_INFO("%s, got p2p_ie\n", __func__);
896
#endif
897
898
#if 1
899
bss = cfg80211_inform_bss_frame(wiphy, notify_channel, (struct ieee80211_mgmt *)pbuf,
900
len, notify_signal, GFP_ATOMIC);
901
#else
902
903
bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)pnetwork->network.MacAddress,
904
notify_timestamp, notify_capability, notify_interval, notify_ie,
905
notify_ielen, notify_signal, GFP_ATOMIC/*GFP_KERNEL*/);
906
#endif
907
908
if (unlikely(!bss)) {
909
RTW_INFO(FUNC_ADPT_FMT" bss NULL\n", FUNC_ADPT_ARG(padapter));
910
goto exit;
911
}
912
913
#ifdef CONFIG_NET_NS
914
wiphy->flags |= WIPHY_FLAG_NETNS_OK;
915
#endif //CONFIG_NET_NS
916
917
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38))
918
#ifndef COMPAT_KERNEL_RELEASE
919
/* patch for cfg80211, update beacon ies to information_elements */
920
if (pnetwork->network.Reserved[0] == BSS_TYPE_BCN) { /* WIFI_BEACON */
921
922
if (bss->len_information_elements != bss->len_beacon_ies) {
923
bss->information_elements = bss->beacon_ies;
924
bss->len_information_elements = bss->len_beacon_ies;
925
}
926
}
927
#endif /* COMPAT_KERNEL_RELEASE */
928
#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38) */
929
930
#if 0
931
{
932
if (bss->information_elements == bss->proberesp_ies) {
933
if (bss->len_information_elements != bss->len_proberesp_ies)
934
RTW_INFO("error!, len_information_elements != bss->len_proberesp_ies\n");
935
} else if (bss->len_information_elements < bss->len_beacon_ies) {
936
bss->information_elements = bss->beacon_ies;
937
bss->len_information_elements = bss->len_beacon_ies;
938
}
939
}
940
#endif
941
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
942
cfg80211_put_bss(wiphy, bss);
943
#else
944
cfg80211_put_bss(bss);
945
#endif
946
947
exit:
948
if (pbuf)
949
rtw_mfree(pbuf, buf_size);
950
return bss;
951
952
}
953
954
/*
955
Check the given bss is valid by kernel API cfg80211_get_bss()
956
@padapter : the given adapter
957
958
return _TRUE if bss is valid, _FALSE for not found.
959
*/
960
int rtw_cfg80211_check_bss(_adapter *padapter)
961
{
962
WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
963
struct cfg80211_bss *bss = NULL;
964
struct ieee80211_channel *notify_channel = NULL;
965
u32 freq;
966
967
if (!(pnetwork) || !(padapter->rtw_wdev))
968
return _FALSE;
969
970
freq = rtw_ch2freq(pnetwork->Configuration.DSConfig);
971
notify_channel = ieee80211_get_channel(padapter->rtw_wdev->wiphy, freq);
972
bss = cfg80211_get_bss(padapter->rtw_wdev->wiphy, notify_channel,
973
pnetwork->MacAddress, pnetwork->Ssid.Ssid,
974
pnetwork->Ssid.SsidLength,
975
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
976
pnetwork->InfrastructureMode == Ndis802_11Infrastructure?IEEE80211_BSS_TYPE_ESS:IEEE80211_BSS_TYPE_IBSS,
977
IEEE80211_PRIVACY(pnetwork->Privacy));
978
#else
979
pnetwork->InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS, pnetwork->InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS);
980
#endif
981
982
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
983
cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
984
#else
985
cfg80211_put_bss(bss);
986
#endif
987
988
return bss != NULL;
989
}
990
991
void rtw_cfg80211_ibss_indicate_connect(_adapter *padapter)
992
{
993
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
994
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
995
struct wireless_dev *pwdev = padapter->rtw_wdev;
996
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
997
struct wiphy *wiphy = pwdev->wiphy;
998
int freq = 2412;
999
struct ieee80211_channel *notify_channel;
1000
#endif
1001
1002
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1003
1004
if (pwdev->iftype != NL80211_IFTYPE_ADHOC)
1005
return;
1006
1007
if (!rtw_cfg80211_check_bss(padapter)) {
1008
WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
1009
struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
1010
1011
if (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE) {
1012
1013
_rtw_memcpy(&cur_network->network, pnetwork, sizeof(WLAN_BSSID_EX));
1014
if (cur_network) {
1015
if (!rtw_cfg80211_inform_bss(padapter, cur_network))
1016
RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
1017
else
1018
RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter));
1019
} else {
1020
RTW_INFO("cur_network is not exist!!!\n");
1021
return ;
1022
}
1023
} else {
1024
if (scanned == NULL)
1025
rtw_warn_on(1);
1026
1027
if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
1028
&& _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
1029
) {
1030
if (!rtw_cfg80211_inform_bss(padapter, scanned))
1031
RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
1032
else {
1033
/* RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
1034
}
1035
} else {
1036
RTW_INFO("scanned & pnetwork compare fail\n");
1037
rtw_warn_on(1);
1038
}
1039
}
1040
1041
if (!rtw_cfg80211_check_bss(padapter))
1042
RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
1043
}
1044
/* notify cfg80211 that device joined an IBSS */
1045
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
1046
freq = rtw_ch2freq(cur_network->network.Configuration.DSConfig);
1047
if (1)
1048
RTW_INFO("chan: %d, freq: %d\n", cur_network->network.Configuration.DSConfig, freq);
1049
notify_channel = ieee80211_get_channel(wiphy, freq);
1050
cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, notify_channel, GFP_ATOMIC);
1051
#else
1052
cfg80211_ibss_joined(padapter->pnetdev, cur_network->network.MacAddress, GFP_ATOMIC);
1053
#endif
1054
}
1055
1056
void rtw_cfg80211_indicate_connect(_adapter *padapter)
1057
{
1058
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1059
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
1060
struct wireless_dev *pwdev = padapter->rtw_wdev;
1061
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1062
_irqL irqL;
1063
#ifdef CONFIG_P2P
1064
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1065
#endif
1066
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1067
struct cfg80211_roam_info roam_info ={};
1068
#endif
1069
1070
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
1071
if (pwdev->iftype != NL80211_IFTYPE_STATION
1072
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1073
&& pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
1074
#endif
1075
)
1076
return;
1077
1078
if (!MLME_IS_STA(padapter))
1079
return;
1080
1081
#ifdef CONFIG_P2P
1082
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1083
#if !RTW_P2P_GROUP_INTERFACE
1084
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1085
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
1086
rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
1087
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
1088
RTW_INFO("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
1089
}
1090
#endif
1091
}
1092
#endif /* CONFIG_P2P */
1093
1094
if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE) {
1095
WLAN_BSSID_EX *pnetwork = &(padapter->mlmeextpriv.mlmext_info.network);
1096
struct wlan_network *scanned = pmlmepriv->cur_network_scanned;
1097
1098
/* RTW_INFO(FUNC_ADPT_FMT" BSS not found\n", FUNC_ADPT_ARG(padapter)); */
1099
1100
if (scanned == NULL) {
1101
rtw_warn_on(1);
1102
goto check_bss;
1103
}
1104
1105
if (_rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
1106
&& _rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
1107
) {
1108
if (!rtw_cfg80211_inform_bss(padapter, scanned))
1109
RTW_INFO(FUNC_ADPT_FMT" inform fail !!\n", FUNC_ADPT_ARG(padapter));
1110
else {
1111
/* RTW_INFO(FUNC_ADPT_FMT" inform success !!\n", FUNC_ADPT_ARG(padapter)); */
1112
}
1113
} else {
1114
RTW_INFO("scanned: %s("MAC_FMT"), cur: %s("MAC_FMT")\n",
1115
scanned->network.Ssid.Ssid, MAC_ARG(scanned->network.MacAddress),
1116
pnetwork->Ssid.Ssid, MAC_ARG(pnetwork->MacAddress)
1117
);
1118
rtw_warn_on(1);
1119
}
1120
}
1121
1122
check_bss:
1123
if (!rtw_cfg80211_check_bss(padapter))
1124
RTW_PRINT(FUNC_ADPT_FMT" BSS not found !!\n", FUNC_ADPT_ARG(padapter));
1125
1126
_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1127
1128
if (rtw_to_roam(padapter) > 0) {
1129
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
1130
struct wiphy *wiphy = pwdev->wiphy;
1131
struct ieee80211_channel *notify_channel;
1132
u32 freq;
1133
u16 channel = cur_network->network.Configuration.DSConfig;
1134
1135
freq = rtw_ch2freq(channel);
1136
notify_channel = ieee80211_get_channel(wiphy, freq);
1137
#endif
1138
1139
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
1140
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 0, 0))
1141
roam_info.links[0].bssid = cur_network->network.MacAddress;
1142
#else
1143
roam_info.bssid = cur_network->network.MacAddress;
1144
#endif
1145
roam_info.req_ie = pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2;
1146
roam_info.req_ie_len = pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2;
1147
roam_info.resp_ie = pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6;
1148
roam_info.resp_ie_len = pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6;
1149
1150
cfg80211_roamed(padapter->pnetdev, &roam_info, GFP_ATOMIC);
1151
#else
1152
cfg80211_roamed(padapter->pnetdev
1153
#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 39) || defined(COMPAT_KERNEL_RELEASE)
1154
, notify_channel
1155
#endif
1156
, cur_network->network.MacAddress
1157
, pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2
1158
, pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2
1159
, pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
1160
, pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6
1161
, GFP_ATOMIC);
1162
#endif /*LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)*/
1163
1164
RTW_INFO(FUNC_ADPT_FMT" call cfg80211_roamed\n", FUNC_ADPT_ARG(padapter));
1165
1166
#ifdef CONFIG_RTW_80211R
1167
if (rtw_ft_roam(padapter))
1168
rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA);
1169
#endif
1170
} else {
1171
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
1172
RTW_INFO("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
1173
#endif
1174
1175
if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) != _TRUE)
1176
rtw_cfg80211_connect_result(pwdev, cur_network->network.MacAddress
1177
, pmlmepriv->assoc_req + sizeof(struct rtw_ieee80211_hdr_3addr) + 2
1178
, pmlmepriv->assoc_req_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 2
1179
, pmlmepriv->assoc_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6
1180
, pmlmepriv->assoc_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6
1181
, WLAN_STATUS_SUCCESS, GFP_ATOMIC);
1182
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
1183
RTW_INFO("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
1184
#endif
1185
}
1186
1187
rtw_wdev_free_connect_req(pwdev_priv);
1188
1189
_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1190
}
1191
1192
void rtw_cfg80211_indicate_disconnect(_adapter *padapter, u16 reason, u8 locally_generated)
1193
{
1194
struct wireless_dev *pwdev = padapter->rtw_wdev;
1195
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1196
_irqL irqL;
1197
#ifdef CONFIG_P2P
1198
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1199
#endif
1200
1201
RTW_INFO(FUNC_ADPT_FMT" ,reason = %d\n", FUNC_ADPT_ARG(padapter), reason);
1202
1203
/*always replace privated definitions with wifi reserved value 0*/
1204
if (WLAN_REASON_IS_PRIVATE(reason))
1205
reason = 0;
1206
1207
if (pwdev->iftype != NL80211_IFTYPE_STATION
1208
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1209
&& pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT
1210
#endif
1211
)
1212
return;
1213
1214
if (!MLME_IS_STA(padapter))
1215
return;
1216
1217
#ifdef CONFIG_P2P
1218
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1219
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
1220
rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
1221
1222
#if RTW_P2P_GROUP_INTERFACE
1223
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1224
if (pwdev->iftype != NL80211_IFTYPE_P2P_CLIENT)
1225
#endif
1226
#endif
1227
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
1228
1229
RTW_INFO("%s, role=%d, p2p_state=%d, pre_p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo), rtw_p2p_pre_state(pwdinfo));
1230
}
1231
}
1232
#endif /* CONFIG_P2P */
1233
1234
_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1235
1236
if (padapter->ndev_unregistering || !rtw_wdev_not_indic_disco(pwdev_priv)) {
1237
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) || defined(COMPAT_KERNEL_RELEASE)
1238
RTW_INFO("pwdev->sme_state(b)=%d\n", pwdev->sme_state);
1239
1240
if (pwdev->sme_state == CFG80211_SME_CONNECTING) {
1241
RTW_INFO(FUNC_ADPT_FMT" call cfg80211_connect_result, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1242
rtw_cfg80211_connect_result(pwdev, NULL, NULL, 0, NULL, 0,
1243
reason?reason:WLAN_STATUS_UNSPECIFIED_FAILURE,
1244
GFP_ATOMIC);
1245
} else if (pwdev->sme_state == CFG80211_SME_CONNECTED) {
1246
RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1247
rtw_cfg80211_disconnected(pwdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
1248
}
1249
1250
RTW_INFO("pwdev->sme_state(a)=%d\n", pwdev->sme_state);
1251
#else
1252
if (pwdev_priv->connect_req) {
1253
RTW_INFO(FUNC_ADPT_FMT" call cfg80211_connect_result, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1254
rtw_cfg80211_connect_result(pwdev, NULL, NULL, 0, NULL, 0,
1255
reason?reason:WLAN_STATUS_UNSPECIFIED_FAILURE,
1256
GFP_ATOMIC);
1257
} else {
1258
RTW_INFO(FUNC_ADPT_FMT" call cfg80211_disconnected, reason:%d\n", FUNC_ADPT_ARG(padapter), reason);
1259
rtw_cfg80211_disconnected(pwdev, reason, NULL, 0, locally_generated, GFP_ATOMIC);
1260
1261
cfg80211_connect_result(padapter->pnetdev, NULL, NULL, 0, NULL, 0,
1262
WLAN_STATUS_UNSPECIFIED_FAILURE, GFP_ATOMIC);
1263
}
1264
#endif
1265
}
1266
1267
rtw_wdev_free_connect_req(pwdev_priv);
1268
1269
_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
1270
}
1271
1272
1273
#ifdef CONFIG_AP_MODE
1274
static int rtw_cfg80211_ap_set_encryption(struct net_device *dev, struct ieee_param *param)
1275
{
1276
int ret = 0;
1277
u32 wep_key_idx, wep_key_len;
1278
struct sta_info *psta = NULL, *pbcmc_sta = NULL;
1279
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1280
struct security_priv *psecuritypriv = &(padapter->securitypriv);
1281
struct sta_priv *pstapriv = &padapter->stapriv;
1282
1283
RTW_INFO("%s\n", __FUNCTION__);
1284
1285
param->u.crypt.err = 0;
1286
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1287
1288
if (is_broadcast_mac_addr(param->sta_addr)) {
1289
if (param->u.crypt.idx >= WEP_KEYS
1290
#ifdef CONFIG_IEEE80211W
1291
&& param->u.crypt.idx > BIP_MAX_KEYID
1292
#endif
1293
) {
1294
ret = -EINVAL;
1295
goto exit;
1296
}
1297
} else {
1298
psta = rtw_get_stainfo(pstapriv, param->sta_addr);
1299
if (!psta) {
1300
ret = -EINVAL;
1301
RTW_INFO(FUNC_ADPT_FMT", sta "MAC_FMT" not found\n"
1302
, FUNC_ADPT_ARG(padapter), MAC_ARG(param->sta_addr));
1303
goto exit;
1304
}
1305
}
1306
1307
if (strcmp(param->u.crypt.alg, "none") == 0 && (psta == NULL)) {
1308
/* todo:clear default encryption keys */
1309
1310
RTW_INFO("clear default encryption keys, keyid=%d\n", param->u.crypt.idx);
1311
1312
goto exit;
1313
}
1314
1315
1316
if (strcmp(param->u.crypt.alg, "WEP") == 0 && (psta == NULL)) {
1317
RTW_INFO("r871x_set_encryption, crypt.alg = WEP\n");
1318
1319
wep_key_idx = param->u.crypt.idx;
1320
wep_key_len = param->u.crypt.key_len;
1321
1322
RTW_INFO("r871x_set_encryption, wep_key_idx=%d, len=%d\n", wep_key_idx, wep_key_len);
1323
1324
if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
1325
ret = -EINVAL;
1326
goto exit;
1327
}
1328
1329
if (wep_key_len > 0)
1330
wep_key_len = wep_key_len <= 5 ? 5 : 13;
1331
1332
if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1333
/* wep default key has not been set, so use this key index as default key. */
1334
1335
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
1336
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1337
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1338
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1339
1340
if (wep_key_len == 13) {
1341
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1342
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1343
}
1344
1345
psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1346
}
1347
1348
_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1349
1350
psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1351
1352
rtw_ap_set_wep_key(padapter, param->u.crypt.key, wep_key_len, wep_key_idx, 1);
1353
1354
goto exit;
1355
1356
}
1357
1358
if (!psta) { /* group key */
1359
if (param->u.crypt.set_tx == 0) { /* group key, TX only */
1360
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1361
RTW_INFO(FUNC_ADPT_FMT" set WEP TX GTK idx:%u, len:%u\n"
1362
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1363
_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));
1364
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1365
if (param->u.crypt.key_len == 13)
1366
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1367
1368
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
1369
RTW_INFO(FUNC_ADPT_FMT" set TKIP TX GTK idx:%u, len:%u\n"
1370
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1371
psecuritypriv->dot118021XGrpPrivacy = _TKIP_;
1372
_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));
1373
/* set mic key */
1374
_rtw_memcpy(psecuritypriv->dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1375
_rtw_memcpy(psecuritypriv->dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1376
psecuritypriv->busetkipkey = _TRUE;
1377
1378
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1379
RTW_INFO(FUNC_ADPT_FMT" set CCMP TX GTK idx:%u, len:%u\n"
1380
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1381
psecuritypriv->dot118021XGrpPrivacy = _AES_;
1382
_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));
1383
1384
#ifdef CONFIG_IEEE80211W
1385
} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1386
RTW_INFO(FUNC_ADPT_FMT" set TX IGTK idx:%u, len:%u\n"
1387
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1388
_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));
1389
padapter->securitypriv.dot11wBIPKeyid = param->u.crypt.idx;
1390
psecuritypriv->dot11wBIPtxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1391
padapter->securitypriv.binstallBIPkey = _TRUE;
1392
goto exit;
1393
#endif /* CONFIG_IEEE80211W */
1394
1395
} else if (strcmp(param->u.crypt.alg, "none") == 0) {
1396
RTW_INFO(FUNC_ADPT_FMT" clear group key, idx:%u\n"
1397
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx);
1398
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
1399
} else {
1400
RTW_WARN(FUNC_ADPT_FMT" set group key, not support\n"
1401
, FUNC_ADPT_ARG(padapter));
1402
goto exit;
1403
}
1404
1405
psecuritypriv->dot118021XGrpKeyid = param->u.crypt.idx;
1406
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1407
if (pbcmc_sta) {
1408
pbcmc_sta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
1409
pbcmc_sta->ieee8021x_blocked = _FALSE;
1410
pbcmc_sta->dot118021XPrivacy = psecuritypriv->dot118021XGrpPrivacy; /* rx will use bmc_sta's dot118021XPrivacy */
1411
}
1412
psecuritypriv->binstallGrpkey = _TRUE;
1413
psecuritypriv->dot11PrivacyAlgrthm = psecuritypriv->dot118021XGrpPrivacy;/* !!! */
1414
1415
rtw_ap_set_group_key(padapter, param->u.crypt.key, psecuritypriv->dot118021XGrpPrivacy, param->u.crypt.idx);
1416
}
1417
1418
goto exit;
1419
1420
}
1421
1422
if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_8021X && psta) { /* psk/802_1x */
1423
if (param->u.crypt.set_tx == 1) {
1424
/* pairwise key */
1425
_rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1426
1427
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1428
RTW_INFO(FUNC_ADPT_FMT" set WEP PTK of "MAC_FMT" idx:%u, len:%u\n"
1429
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1430
, param->u.crypt.idx, param->u.crypt.key_len);
1431
psta->dot118021XPrivacy = _WEP40_;
1432
if (param->u.crypt.key_len == 13)
1433
psta->dot118021XPrivacy = _WEP104_;
1434
1435
} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
1436
RTW_INFO(FUNC_ADPT_FMT" set TKIP PTK of "MAC_FMT" idx:%u, len:%u\n"
1437
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1438
, param->u.crypt.idx, param->u.crypt.key_len);
1439
psta->dot118021XPrivacy = _TKIP_;
1440
/* set mic key */
1441
_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1442
_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1443
psecuritypriv->busetkipkey = _TRUE;
1444
1445
} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1446
RTW_INFO(FUNC_ADPT_FMT" set CCMP PTK of "MAC_FMT" idx:%u, len:%u\n"
1447
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1448
, param->u.crypt.idx, param->u.crypt.key_len);
1449
psta->dot118021XPrivacy = _AES_;
1450
1451
} else if (strcmp(param->u.crypt.alg, "none") == 0) {
1452
RTW_INFO(FUNC_ADPT_FMT" clear pairwise key of "MAC_FMT" idx:%u\n"
1453
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1454
, param->u.crypt.idx);
1455
psta->dot118021XPrivacy = _NO_PRIVACY_;
1456
} else {
1457
RTW_WARN(FUNC_ADPT_FMT" set pairwise key of "MAC_FMT", not support\n"
1458
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
1459
goto exit;
1460
}
1461
1462
psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
1463
psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1464
psta->ieee8021x_blocked = _FALSE;
1465
1466
if (psta->dot118021XPrivacy != _NO_PRIVACY_) {
1467
psta->bpairwise_key_installed = _TRUE;
1468
1469
/* WPA2 key-handshake has completed */
1470
if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPA2PSK)
1471
psta->state &= (~WIFI_UNDER_KEY_HANDSHAKE);
1472
}
1473
1474
rtw_ap_set_pairwise_key(padapter, psta);
1475
} else {
1476
/* peer's group key, RX only */
1477
#ifdef CONFIG_RTW_MESH
1478
if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
1479
RTW_INFO(FUNC_ADPT_FMT" set CCMP GTK of "MAC_FMT", idx:%u, len:%u\n"
1480
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1481
, param->u.crypt.idx, param->u.crypt.key_len);
1482
psta->group_privacy = _AES_;
1483
_rtw_memcpy(psta->gtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1484
psta->gtk_bmp |= BIT(param->u.crypt.idx);
1485
psta->gtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1486
1487
#ifdef CONFIG_IEEE80211W
1488
} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1489
RTW_INFO(FUNC_ADPT_FMT" set IGTK of "MAC_FMT", idx:%u, len:%u\n"
1490
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1491
, param->u.crypt.idx, param->u.crypt.key_len);
1492
_rtw_memcpy(psta->igtk.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1493
psta->igtk_bmp |= BIT(param->u.crypt.idx);
1494
psta->igtk_id = param->u.crypt.idx;
1495
psta->igtk_pn.val = RTW_GET_LE64(param->u.crypt.seq);
1496
goto exit;
1497
#endif /* CONFIG_IEEE80211W */
1498
1499
} else if (strcmp(param->u.crypt.alg, "none") == 0) {
1500
RTW_INFO(FUNC_ADPT_FMT" clear group key of "MAC_FMT", idx:%u\n"
1501
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr)
1502
, param->u.crypt.idx);
1503
psta->group_privacy = _NO_PRIVACY_;
1504
psta->gtk_bmp &= ~BIT(param->u.crypt.idx);
1505
} else
1506
#endif /* CONFIG_RTW_MESH */
1507
{
1508
RTW_WARN(FUNC_ADPT_FMT" set group key of "MAC_FMT", not support\n"
1509
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
1510
goto exit;
1511
}
1512
1513
#ifdef CONFIG_RTW_MESH
1514
rtw_ap_set_sta_key(padapter, psta->cmn.mac_addr, psta->group_privacy
1515
, param->u.crypt.key, param->u.crypt.idx, 1);
1516
#endif
1517
}
1518
1519
}
1520
1521
exit:
1522
return ret;
1523
}
1524
#endif /* CONFIG_AP_MODE */
1525
1526
static int rtw_cfg80211_set_encryption(struct net_device *dev, struct ieee_param *param)
1527
{
1528
int ret = 0;
1529
u32 wep_key_idx, wep_key_len;
1530
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
1531
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1532
struct security_priv *psecuritypriv = &padapter->securitypriv;
1533
#ifdef CONFIG_P2P
1534
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1535
#endif /* CONFIG_P2P */
1536
1537
RTW_INFO("%s\n", __func__);
1538
1539
param->u.crypt.err = 0;
1540
param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
1541
1542
if (is_broadcast_mac_addr(param->sta_addr)) {
1543
if (param->u.crypt.idx >= WEP_KEYS
1544
#ifdef CONFIG_IEEE80211W
1545
&& param->u.crypt.idx > BIP_MAX_KEYID
1546
#endif
1547
) {
1548
ret = -EINVAL;
1549
goto exit;
1550
}
1551
} else {
1552
#ifdef CONFIG_WAPI_SUPPORT
1553
if (strcmp(param->u.crypt.alg, "SMS4"))
1554
#endif
1555
{
1556
ret = -EINVAL;
1557
goto exit;
1558
}
1559
}
1560
1561
if (strcmp(param->u.crypt.alg, "WEP") == 0) {
1562
RTW_INFO("wpa_set_encryption, crypt.alg = WEP\n");
1563
1564
wep_key_idx = param->u.crypt.idx;
1565
wep_key_len = param->u.crypt.key_len;
1566
1567
if ((wep_key_idx >= WEP_KEYS) || (wep_key_len <= 0)) {
1568
ret = -EINVAL;
1569
goto exit;
1570
}
1571
1572
if (psecuritypriv->bWepDefaultKeyIdxSet == 0) {
1573
/* wep default key has not been set, so use this key index as default key. */
1574
1575
wep_key_len = wep_key_len <= 5 ? 5 : 13;
1576
1577
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
1578
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
1579
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
1580
1581
if (wep_key_len == 13) {
1582
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
1583
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
1584
}
1585
1586
psecuritypriv->dot11PrivacyKeyIndex = wep_key_idx;
1587
}
1588
1589
_rtw_memcpy(&(psecuritypriv->dot11DefKey[wep_key_idx].skey[0]), param->u.crypt.key, wep_key_len);
1590
1591
psecuritypriv->dot11DefKeylen[wep_key_idx] = wep_key_len;
1592
1593
rtw_set_key(padapter, psecuritypriv, wep_key_idx, 0, _TRUE);
1594
1595
goto exit;
1596
}
1597
1598
if (padapter->securitypriv.dot11AuthAlgrthm == dot11AuthAlgrthm_8021X) { /* 802_1x */
1599
struct sta_info *psta, *pbcmc_sta;
1600
struct sta_priv *pstapriv = &padapter->stapriv;
1601
1602
/* RTW_INFO("%s, : dot11AuthAlgrthm == dot11AuthAlgrthm_8021X\n", __func__); */
1603
1604
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_MP_STATE) == _TRUE) { /* sta mode */
1605
#ifdef CONFIG_RTW_80211R
1606
if (rtw_ft_roam(padapter))
1607
psta = rtw_get_stainfo(pstapriv, pmlmepriv->assoc_bssid);
1608
else
1609
#endif
1610
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
1611
if (psta == NULL) {
1612
/* DEBUG_ERR( ("Set wpa_set_encryption: Obtain Sta_info fail\n")); */
1613
RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);
1614
} else {
1615
/* Jeff: don't disable ieee8021x_blocked while clearing key */
1616
if (strcmp(param->u.crypt.alg, "none") != 0)
1617
psta->ieee8021x_blocked = _FALSE;
1618
1619
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1620
(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1621
psta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1622
1623
if (param->u.crypt.set_tx == 1) { /* pairwise key */
1624
RTW_INFO(FUNC_ADPT_FMT" set %s PTK idx:%u, len:%u\n"
1625
, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
1626
_rtw_memcpy(psta->dot118021x_UncstKey.skey, param->u.crypt.key, (param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1627
if (strcmp(param->u.crypt.alg, "TKIP") == 0) { /* set mic key */
1628
_rtw_memcpy(psta->dot11tkiptxmickey.skey, &(param->u.crypt.key[16]), 8);
1629
_rtw_memcpy(psta->dot11tkiprxmickey.skey, &(param->u.crypt.key[24]), 8);
1630
padapter->securitypriv.busetkipkey = _FALSE;
1631
}
1632
psta->dot11txpn.val = RTW_GET_LE64(param->u.crypt.seq);
1633
psta->dot11rxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1634
psta->bpairwise_key_installed = _TRUE;
1635
#ifdef CONFIG_RTW_80211R
1636
psta->ft_pairwise_key_installed = _TRUE;
1637
#endif
1638
rtw_setstakey_cmd(padapter, psta, UNICAST_KEY, _TRUE);
1639
1640
} else { /* group key */
1641
if (strcmp(param->u.crypt.alg, "TKIP") == 0 || strcmp(param->u.crypt.alg, "CCMP") == 0) {
1642
RTW_INFO(FUNC_ADPT_FMT" set %s GTK idx:%u, len:%u\n"
1643
, FUNC_ADPT_ARG(padapter), param->u.crypt.alg, param->u.crypt.idx, param->u.crypt.key_len);
1644
_rtw_memcpy(padapter->securitypriv.dot118021XGrpKey[param->u.crypt.idx].skey, param->u.crypt.key,
1645
(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1646
_rtw_memcpy(padapter->securitypriv.dot118021XGrptxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[16]), 8);
1647
_rtw_memcpy(padapter->securitypriv.dot118021XGrprxmickey[param->u.crypt.idx].skey, &(param->u.crypt.key[24]), 8);
1648
padapter->securitypriv.binstallGrpkey = _TRUE;
1649
if (param->u.crypt.idx < 4)
1650
_rtw_memcpy(padapter->securitypriv.iv_seq[param->u.crypt.idx], param->u.crypt.seq, 8);
1651
padapter->securitypriv.dot118021XGrpKeyid = param->u.crypt.idx;
1652
rtw_set_key(padapter, &padapter->securitypriv, param->u.crypt.idx, 1, _TRUE);
1653
1654
#ifdef CONFIG_IEEE80211W
1655
} else if (strcmp(param->u.crypt.alg, "BIP") == 0) {
1656
RTW_INFO(FUNC_ADPT_FMT" set IGTK idx:%u, len:%u\n"
1657
, FUNC_ADPT_ARG(padapter), param->u.crypt.idx, param->u.crypt.key_len);
1658
_rtw_memcpy(padapter->securitypriv.dot11wBIPKey[param->u.crypt.idx].skey, param->u.crypt.key,
1659
(param->u.crypt.key_len > 16 ? 16 : param->u.crypt.key_len));
1660
psecuritypriv->dot11wBIPKeyid = param->u.crypt.idx;
1661
psecuritypriv->dot11wBIPrxpn.val = RTW_GET_LE64(param->u.crypt.seq);
1662
psecuritypriv->binstallBIPkey = _TRUE;
1663
#endif /* CONFIG_IEEE80211W */
1664
1665
}
1666
1667
#ifdef CONFIG_P2P
1668
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
1669
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_PROVISIONING_ING))
1670
rtw_p2p_set_state(pwdinfo, P2P_STATE_PROVISIONING_DONE);
1671
}
1672
#endif /* CONFIG_P2P */
1673
1674
/* WPA/WPA2 key-handshake has completed */
1675
clr_fwstate(pmlmepriv, WIFI_UNDER_KEY_HANDSHAKE);
1676
1677
}
1678
}
1679
1680
pbcmc_sta = rtw_get_bcmc_stainfo(padapter);
1681
if (pbcmc_sta == NULL) {
1682
/* DEBUG_ERR( ("Set OID_802_11_ADD_KEY: bcmc stainfo is null\n")); */
1683
} else {
1684
/* Jeff: don't disable ieee8021x_blocked while clearing key */
1685
if (strcmp(param->u.crypt.alg, "none") != 0)
1686
pbcmc_sta->ieee8021x_blocked = _FALSE;
1687
1688
if ((padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption2Enabled) ||
1689
(padapter->securitypriv.ndisencryptstatus == Ndis802_11Encryption3Enabled))
1690
pbcmc_sta->dot118021XPrivacy = padapter->securitypriv.dot11PrivacyAlgrthm;
1691
}
1692
} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE)) { /* adhoc mode */
1693
}
1694
}
1695
1696
#ifdef CONFIG_WAPI_SUPPORT
1697
if (strcmp(param->u.crypt.alg, "SMS4") == 0)
1698
rtw_wapi_set_set_encryption(padapter, param);
1699
#endif
1700
1701
exit:
1702
1703
RTW_INFO("%s, ret=%d\n", __func__, ret);
1704
1705
1706
return ret;
1707
}
1708
1709
static int cfg80211_rtw_add_key(struct wiphy *wiphy, struct net_device *ndev
1710
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
1711
, int link_id
1712
#endif
1713
, u8 key_index
1714
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1715
, bool pairwise
1716
#endif
1717
, const u8 *mac_addr, struct key_params *params)
1718
{
1719
char *alg_name;
1720
u32 param_len;
1721
struct ieee_param *param = NULL;
1722
int ret = 0;
1723
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
1724
struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
1725
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1726
#ifdef CONFIG_TDLS
1727
struct sta_info *ptdls_sta;
1728
#endif /* CONFIG_TDLS */
1729
1730
if (mac_addr)
1731
RTW_INFO(FUNC_NDEV_FMT" adding key for %pM\n", FUNC_NDEV_ARG(ndev), mac_addr);
1732
RTW_INFO(FUNC_NDEV_FMT" cipher=0x%x\n", FUNC_NDEV_ARG(ndev), params->cipher);
1733
RTW_INFO(FUNC_NDEV_FMT" key_len=%d, key_index=%d\n", FUNC_NDEV_ARG(ndev), params->key_len, key_index);
1734
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1735
RTW_INFO(FUNC_NDEV_FMT" pairwise=%d\n", FUNC_NDEV_ARG(ndev), pairwise);
1736
#endif
1737
1738
if (rtw_cfg80211_sync_iftype(padapter) != _SUCCESS) {
1739
ret = -ENOTSUPP;
1740
goto addkey_end;
1741
}
1742
1743
param_len = sizeof(struct ieee_param) + params->key_len;
1744
param = rtw_malloc(param_len);
1745
if (param == NULL)
1746
return -1;
1747
1748
_rtw_memset(param, 0, param_len);
1749
1750
param->cmd = IEEE_CMD_SET_ENCRYPTION;
1751
_rtw_memset(param->sta_addr, 0xff, ETH_ALEN);
1752
1753
switch (params->cipher) {
1754
case IW_AUTH_CIPHER_NONE:
1755
/* todo: remove key */
1756
/* remove = 1; */
1757
alg_name = "none";
1758
break;
1759
case WLAN_CIPHER_SUITE_WEP40:
1760
case WLAN_CIPHER_SUITE_WEP104:
1761
alg_name = "WEP";
1762
break;
1763
case WLAN_CIPHER_SUITE_TKIP:
1764
alg_name = "TKIP";
1765
break;
1766
case WLAN_CIPHER_SUITE_CCMP:
1767
alg_name = "CCMP";
1768
break;
1769
#ifdef CONFIG_IEEE80211W
1770
case WLAN_CIPHER_SUITE_AES_CMAC:
1771
alg_name = "BIP";
1772
break;
1773
#endif /* CONFIG_IEEE80211W */
1774
#ifdef CONFIG_WAPI_SUPPORT
1775
case WLAN_CIPHER_SUITE_SMS4:
1776
alg_name = "SMS4";
1777
if (pairwise == NL80211_KEYTYPE_PAIRWISE) {
1778
if (key_index != 0 && key_index != 1) {
1779
ret = -ENOTSUPP;
1780
goto addkey_end;
1781
}
1782
_rtw_memcpy((void *)param->sta_addr, (void *)mac_addr, ETH_ALEN);
1783
} else
1784
RTW_INFO("mac_addr is null\n");
1785
RTW_INFO("rtw_wx_set_enc_ext: SMS4 case\n");
1786
break;
1787
#endif
1788
1789
default:
1790
ret = -ENOTSUPP;
1791
goto addkey_end;
1792
}
1793
1794
strncpy((char *)param->u.crypt.alg, alg_name, IEEE_CRYPT_ALG_NAME_LEN);
1795
1796
1797
if (!mac_addr || is_broadcast_ether_addr(mac_addr)
1798
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1799
|| !pairwise
1800
#endif
1801
) {
1802
param->u.crypt.set_tx = 0; /* for wpa/wpa2 group key */
1803
} else {
1804
param->u.crypt.set_tx = 1; /* for wpa/wpa2 pairwise key */
1805
}
1806
1807
param->u.crypt.idx = key_index;
1808
1809
if (params->seq_len && params->seq) {
1810
_rtw_memcpy(param->u.crypt.seq, (u8 *)params->seq, params->seq_len);
1811
RTW_INFO(FUNC_NDEV_FMT" seq_len:%u, seq:0x%llx\n", FUNC_NDEV_ARG(ndev)
1812
, params->seq_len, RTW_GET_LE64(param->u.crypt.seq));
1813
}
1814
1815
if (params->key_len && params->key) {
1816
param->u.crypt.key_len = params->key_len;
1817
_rtw_memcpy(param->u.crypt.key, (u8 *)params->key, params->key_len);
1818
}
1819
1820
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
1821
#ifdef CONFIG_TDLS
1822
if (rtw_tdls_is_driver_setup(padapter) == _FALSE && mac_addr) {
1823
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, (void *)mac_addr);
1824
if (ptdls_sta != NULL && ptdls_sta->tdls_sta_state) {
1825
_rtw_memcpy(ptdls_sta->tpk.tk, params->key, params->key_len);
1826
rtw_tdls_set_key(padapter, ptdls_sta);
1827
goto addkey_end;
1828
}
1829
}
1830
#endif /* CONFIG_TDLS */
1831
ret = rtw_cfg80211_set_encryption(ndev, param);
1832
} else if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
1833
#ifdef CONFIG_AP_MODE
1834
if (mac_addr)
1835
_rtw_memcpy(param->sta_addr, (void *)mac_addr, ETH_ALEN);
1836
1837
ret = rtw_cfg80211_ap_set_encryption(ndev, param);
1838
#endif
1839
} else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE
1840
|| check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE
1841
) {
1842
/* RTW_INFO("@@@@@@@@@@ fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype); */
1843
ret = rtw_cfg80211_set_encryption(ndev, param);
1844
} else
1845
RTW_INFO("error! fw_state=0x%x, iftype=%d\n", pmlmepriv->fw_state, rtw_wdev->iftype);
1846
1847
1848
addkey_end:
1849
if (param)
1850
rtw_mfree(param, param_len);
1851
1852
return ret;
1853
1854
}
1855
1856
static int cfg80211_rtw_get_key(struct wiphy *wiphy, struct net_device *ndev
1857
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
1858
, int link_id
1859
#endif
1860
, u8 keyid
1861
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1862
, bool pairwise
1863
#endif
1864
, const u8 *mac_addr, void *cookie
1865
, void (*callback)(void *cookie, struct key_params *))
1866
{
1867
#define GET_KEY_PARAM_FMT_S " keyid=%d"
1868
#define GET_KEY_PARAM_ARG_S , keyid
1869
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1870
#define GET_KEY_PARAM_FMT_2_6_37 ", pairwise=%d"
1871
#define GET_KEY_PARAM_ARG_2_6_37 , pairwise
1872
#else
1873
#define GET_KEY_PARAM_FMT_2_6_37 ""
1874
#define GET_KEY_PARAM_ARG_2_6_37
1875
#endif
1876
#define GET_KEY_PARAM_FMT_E ", addr=%pM"
1877
#define GET_KEY_PARAM_ARG_E , mac_addr
1878
1879
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
1880
struct security_priv *sec = &adapter->securitypriv;
1881
struct sta_priv *stapriv = &adapter->stapriv;
1882
struct sta_info *sta = NULL;
1883
u32 cipher = _NO_PRIVACY_;
1884
union Keytype *key = NULL;
1885
u8 key_len = 0;
1886
u64 *pn = NULL;
1887
u8 pn_len = 0;
1888
u8 pn_val[8] = {0};
1889
1890
struct key_params params;
1891
int ret = -ENOENT;
1892
1893
if (keyid >= WEP_KEYS
1894
#ifdef CONFIG_IEEE80211W
1895
&& keyid > BIP_MAX_KEYID
1896
#endif
1897
)
1898
goto exit;
1899
1900
if (!mac_addr || is_broadcast_ether_addr(mac_addr)
1901
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
1902
|| (MLME_IS_STA(adapter) && !pairwise)
1903
#endif
1904
) {
1905
/* WEP key, TX GTK/IGTK, RX GTK/IGTK(for STA mode) */
1906
if (is_wep_enc(sec->dot118021XGrpPrivacy)) {
1907
if (keyid >= WEP_KEYS)
1908
goto exit;
1909
if (!(sec->key_mask & BIT(keyid)))
1910
goto exit;
1911
cipher = sec->dot118021XGrpPrivacy;
1912
key = &sec->dot11DefKey[keyid];
1913
} else {
1914
if (keyid < WEP_KEYS) {
1915
if (sec->binstallGrpkey != _TRUE)
1916
goto exit;
1917
cipher = sec->dot118021XGrpPrivacy;
1918
key = &sec->dot118021XGrpKey[keyid];
1919
sta = rtw_get_bcmc_stainfo(adapter);
1920
if (sta)
1921
pn = &sta->dot11txpn.val;
1922
#ifdef CONFIG_IEEE80211W
1923
} else if (keyid <= BIP_MAX_KEYID) {
1924
if (SEC_IS_BIP_KEY_INSTALLED(sec) != _TRUE)
1925
goto exit;
1926
cipher = _BIP_;
1927
key = &sec->dot11wBIPKey[keyid];
1928
pn = &sec->dot11wBIPtxpn.val;
1929
#endif
1930
}
1931
}
1932
} else {
1933
/* Pairwise key, RX GTK/IGTK for specific peer */
1934
sta = rtw_get_stainfo(stapriv, mac_addr);
1935
if (!sta)
1936
goto exit;
1937
1938
if (keyid < WEP_KEYS && pairwise) {
1939
if (sta->bpairwise_key_installed != _TRUE)
1940
goto exit;
1941
cipher = sta->dot118021XPrivacy;
1942
key = &sta->dot118021x_UncstKey;
1943
#ifdef CONFIG_RTW_MESH
1944
} else if (keyid < WEP_KEYS && !pairwise) {
1945
if (!(sta->gtk_bmp & BIT(keyid)))
1946
goto exit;
1947
cipher = sta->group_privacy;
1948
key = &sta->gtk;
1949
#ifdef CONFIG_IEEE80211W
1950
} else if (keyid <= BIP_MAX_KEYID && !pairwise) {
1951
if (!(sta->igtk_bmp & BIT(keyid)))
1952
goto exit;
1953
cipher = _BIP_;
1954
key = &sta->igtk;
1955
pn = &sta->igtk_pn.val;
1956
#endif
1957
#endif /* CONFIG_RTW_MESH */
1958
}
1959
}
1960
1961
if (!key)
1962
goto exit;
1963
1964
if (cipher == _WEP40_) {
1965
cipher = WLAN_CIPHER_SUITE_WEP40;
1966
key_len = sec->dot11DefKeylen[keyid];
1967
} else if (cipher == _WEP104_) {
1968
cipher = WLAN_CIPHER_SUITE_WEP104;
1969
key_len = sec->dot11DefKeylen[keyid];
1970
} else if (cipher == _TKIP_) {
1971
cipher = WLAN_CIPHER_SUITE_TKIP;
1972
key_len = 16;
1973
} else if (cipher == _AES_) {
1974
cipher = WLAN_CIPHER_SUITE_CCMP;
1975
key_len = 16;
1976
#ifdef CONFIG_IEEE80211W
1977
} else if (cipher == _BIP_) {
1978
cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1979
key_len = 16;
1980
#endif
1981
} else {
1982
RTW_WARN(FUNC_NDEV_FMT" unknown cipher:%u\n", FUNC_NDEV_ARG(ndev), cipher);
1983
rtw_warn_on(1);
1984
goto exit;
1985
}
1986
1987
if (pn) {
1988
*((u64 *)pn_val) = cpu_to_le64(*pn);
1989
pn_len = 6;
1990
}
1991
1992
ret = 0;
1993
1994
exit:
1995
RTW_INFO(FUNC_NDEV_FMT
1996
GET_KEY_PARAM_FMT_S
1997
GET_KEY_PARAM_FMT_2_6_37
1998
GET_KEY_PARAM_FMT_E
1999
" ret %d\n", FUNC_NDEV_ARG(ndev)
2000
GET_KEY_PARAM_ARG_S
2001
GET_KEY_PARAM_ARG_2_6_37
2002
GET_KEY_PARAM_ARG_E
2003
, ret);
2004
if (pn)
2005
RTW_INFO(FUNC_NDEV_FMT " seq:0x%llx\n", FUNC_NDEV_ARG(ndev), *pn);
2006
2007
if (ret == 0) {
2008
_rtw_memset(&params, 0, sizeof(params));
2009
2010
params.cipher = cipher;
2011
params.key = key->skey;
2012
params.key_len = key_len;
2013
if (pn) {
2014
params.seq = pn_val;
2015
params.seq_len = pn_len;
2016
}
2017
2018
callback(cookie, &params);
2019
}
2020
2021
return ret;
2022
}
2023
2024
static int cfg80211_rtw_del_key(struct wiphy *wiphy, struct net_device *ndev,
2025
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
2026
int link_id,
2027
#endif
2028
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2029
u8 key_index, bool pairwise, const u8 *mac_addr)
2030
#else /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
2031
u8 key_index, const u8 *mac_addr)
2032
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) */
2033
{
2034
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2035
struct security_priv *psecuritypriv = &padapter->securitypriv;
2036
2037
RTW_INFO(FUNC_NDEV_FMT" key_index=%d, addr=%pM\n", FUNC_NDEV_ARG(ndev), key_index, mac_addr);
2038
2039
if (key_index == psecuritypriv->dot11PrivacyKeyIndex) {
2040
/* clear the flag of wep default key set. */
2041
psecuritypriv->bWepDefaultKeyIdxSet = 0;
2042
}
2043
2044
return 0;
2045
}
2046
2047
static int cfg80211_rtw_set_default_key(struct wiphy *wiphy,
2048
struct net_device *ndev,
2049
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
2050
int link_id,
2051
#endif
2052
u8 key_index
2053
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
2054
, bool unicast, bool multicast
2055
#endif
2056
)
2057
{
2058
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2059
struct security_priv *psecuritypriv = &padapter->securitypriv;
2060
2061
#define SET_DEF_KEY_PARAM_FMT " key_index=%d"
2062
#define SET_DEF_KEY_PARAM_ARG , key_index
2063
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
2064
#define SET_DEF_KEY_PARAM_FMT_2_6_38 ", unicast=%d, multicast=%d"
2065
#define SET_DEF_KEY_PARAM_ARG_2_6_38 , unicast, multicast
2066
#else
2067
#define SET_DEF_KEY_PARAM_FMT_2_6_38 ""
2068
#define SET_DEF_KEY_PARAM_ARG_2_6_38
2069
#endif
2070
2071
RTW_INFO(FUNC_NDEV_FMT
2072
SET_DEF_KEY_PARAM_FMT
2073
SET_DEF_KEY_PARAM_FMT_2_6_38
2074
"\n", FUNC_NDEV_ARG(ndev)
2075
SET_DEF_KEY_PARAM_ARG
2076
SET_DEF_KEY_PARAM_ARG_2_6_38
2077
);
2078
2079
if ((key_index < WEP_KEYS) && ((psecuritypriv->dot11PrivacyAlgrthm == _WEP40_) || (psecuritypriv->dot11PrivacyAlgrthm == _WEP104_))) { /* set wep default key */
2080
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
2081
2082
psecuritypriv->dot11PrivacyKeyIndex = key_index;
2083
2084
psecuritypriv->dot11PrivacyAlgrthm = _WEP40_;
2085
psecuritypriv->dot118021XGrpPrivacy = _WEP40_;
2086
if (psecuritypriv->dot11DefKeylen[key_index] == 13) {
2087
psecuritypriv->dot11PrivacyAlgrthm = _WEP104_;
2088
psecuritypriv->dot118021XGrpPrivacy = _WEP104_;
2089
}
2090
2091
psecuritypriv->bWepDefaultKeyIdxSet = 1; /* set the flag to represent that wep default key has been set */
2092
}
2093
2094
return 0;
2095
2096
}
2097
2098
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
2099
int cfg80211_rtw_set_default_mgmt_key(struct wiphy *wiphy,
2100
struct net_device *ndev,
2101
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
2102
int link_id,
2103
#endif
2104
u8 key_index)
2105
{
2106
#define SET_DEF_KEY_PARAM_FMT " key_index=%d"
2107
#define SET_DEF_KEY_PARAM_ARG , key_index
2108
2109
RTW_INFO(FUNC_NDEV_FMT
2110
SET_DEF_KEY_PARAM_FMT
2111
"\n", FUNC_NDEV_ARG(ndev)
2112
SET_DEF_KEY_PARAM_ARG
2113
);
2114
2115
return 0;
2116
}
2117
#endif
2118
2119
#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
2120
static int cfg80211_rtw_set_rekey_data(struct wiphy *wiphy,
2121
struct net_device *ndev,
2122
struct cfg80211_gtk_rekey_data *data)
2123
{
2124
/*int i;*/
2125
struct sta_info *psta;
2126
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2127
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2128
struct sta_priv *pstapriv = &padapter->stapriv;
2129
struct security_priv *psecuritypriv = &(padapter->securitypriv);
2130
2131
psta = rtw_get_stainfo(pstapriv, get_bssid(pmlmepriv));
2132
if (psta == NULL) {
2133
RTW_INFO("%s, : Obtain Sta_info fail\n", __func__);
2134
return -1;
2135
}
2136
2137
_rtw_memcpy(psta->kek, data->kek, NL80211_KEK_LEN);
2138
/*printk("\ncfg80211_rtw_set_rekey_data KEK:");
2139
for(i=0;i<NL80211_KEK_LEN; i++)
2140
printk(" %02x ", psta->kek[i]);*/
2141
_rtw_memcpy(psta->kck, data->kck, NL80211_KCK_LEN);
2142
/*printk("\ncfg80211_rtw_set_rekey_data KCK:");
2143
for(i=0;i<NL80211_KCK_LEN; i++)
2144
printk(" %02x ", psta->kck[i]);*/
2145
_rtw_memcpy(psta->replay_ctr, data->replay_ctr, NL80211_REPLAY_CTR_LEN);
2146
psecuritypriv->binstallKCK_KEK = _TRUE;
2147
/*printk("\nREPLAY_CTR: ");
2148
for(i=0;i<RTW_REPLAY_CTR_LEN; i++)
2149
printk(" %02x ", psta->replay_ctr[i]);*/
2150
2151
return 0;
2152
}
2153
#endif /*CONFIG_GTK_OL*/
2154
2155
#ifdef CONFIG_RTW_MESH
2156
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2157
static enum nl80211_mesh_power_mode rtw_mesh_ps_to_nl80211_mesh_power_mode(u8 ps)
2158
{
2159
if (ps == RTW_MESH_PS_UNKNOWN)
2160
return NL80211_MESH_POWER_UNKNOWN;
2161
if (ps == RTW_MESH_PS_ACTIVE)
2162
return NL80211_MESH_POWER_ACTIVE;
2163
if (ps == RTW_MESH_PS_LSLEEP)
2164
return NL80211_MESH_POWER_LIGHT_SLEEP;
2165
if (ps == RTW_MESH_PS_DSLEEP)
2166
return NL80211_MESH_POWER_DEEP_SLEEP;
2167
2168
rtw_warn_on(1);
2169
return NL80211_MESH_POWER_UNKNOWN;
2170
}
2171
#endif
2172
2173
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
2174
enum nl80211_plink_state rtw_plink_state_to_nl80211_plink_state(u8 plink_state)
2175
{
2176
if (plink_state == RTW_MESH_PLINK_UNKNOWN)
2177
return NUM_NL80211_PLINK_STATES;
2178
if (plink_state == RTW_MESH_PLINK_LISTEN)
2179
return NL80211_PLINK_LISTEN;
2180
if (plink_state == RTW_MESH_PLINK_OPN_SNT)
2181
return NL80211_PLINK_OPN_SNT;
2182
if (plink_state == RTW_MESH_PLINK_OPN_RCVD)
2183
return NL80211_PLINK_OPN_RCVD;
2184
if (plink_state == RTW_MESH_PLINK_CNF_RCVD)
2185
return NL80211_PLINK_CNF_RCVD;
2186
if (plink_state == RTW_MESH_PLINK_ESTAB)
2187
return NL80211_PLINK_ESTAB;
2188
if (plink_state == RTW_MESH_PLINK_HOLDING)
2189
return NL80211_PLINK_HOLDING;
2190
if (plink_state == RTW_MESH_PLINK_BLOCKED)
2191
return NL80211_PLINK_BLOCKED;
2192
2193
rtw_warn_on(1);
2194
return NUM_NL80211_PLINK_STATES;
2195
}
2196
2197
u8 nl80211_plink_state_to_rtw_plink_state(enum nl80211_plink_state plink_state)
2198
{
2199
if (plink_state == NL80211_PLINK_LISTEN)
2200
return RTW_MESH_PLINK_LISTEN;
2201
if (plink_state == NL80211_PLINK_OPN_SNT)
2202
return RTW_MESH_PLINK_OPN_SNT;
2203
if (plink_state == NL80211_PLINK_OPN_RCVD)
2204
return RTW_MESH_PLINK_OPN_RCVD;
2205
if (plink_state == NL80211_PLINK_CNF_RCVD)
2206
return RTW_MESH_PLINK_CNF_RCVD;
2207
if (plink_state == NL80211_PLINK_ESTAB)
2208
return RTW_MESH_PLINK_ESTAB;
2209
if (plink_state == NL80211_PLINK_HOLDING)
2210
return RTW_MESH_PLINK_HOLDING;
2211
if (plink_state == NL80211_PLINK_BLOCKED)
2212
return RTW_MESH_PLINK_BLOCKED;
2213
2214
rtw_warn_on(1);
2215
return RTW_MESH_PLINK_UNKNOWN;
2216
}
2217
#endif
2218
2219
static void rtw_cfg80211_fill_mesh_only_sta_info(struct mesh_plink_ent *plink, struct sta_info *sta, struct station_info *sinfo)
2220
{
2221
sinfo->filled |= STATION_INFO_LLID;
2222
sinfo->llid = plink->llid;
2223
sinfo->filled |= STATION_INFO_PLID;
2224
sinfo->plid = plink->plid;
2225
sinfo->filled |= STATION_INFO_PLINK_STATE;
2226
sinfo->plink_state = rtw_plink_state_to_nl80211_plink_state(plink->plink_state);
2227
if (!sta && plink->scanned) {
2228
sinfo->filled |= STATION_INFO_SIGNAL;
2229
sinfo->signal = translate_percentage_to_dbm(plink->scanned->network.PhyInfo.SignalStrength);
2230
sinfo->filled |= STATION_INFO_INACTIVE_TIME;
2231
if (plink->plink_state == RTW_MESH_PLINK_UNKNOWN)
2232
sinfo->inactive_time = 0 - 1;
2233
else
2234
sinfo->inactive_time = rtw_get_passing_time_ms(plink->scanned->last_scanned);
2235
}
2236
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
2237
if (sta) {
2238
sinfo->filled |= STATION_INFO_LOCAL_PM;
2239
sinfo->local_pm = rtw_mesh_ps_to_nl80211_mesh_power_mode(sta->local_mps);
2240
sinfo->filled |= STATION_INFO_PEER_PM;
2241
sinfo->peer_pm = rtw_mesh_ps_to_nl80211_mesh_power_mode(sta->peer_mps);
2242
sinfo->filled |= STATION_INFO_NONPEER_PM;
2243
sinfo->nonpeer_pm = rtw_mesh_ps_to_nl80211_mesh_power_mode(sta->nonpeer_mps);
2244
}
2245
#endif
2246
}
2247
#endif /* CONFIG_RTW_MESH */
2248
2249
static int cfg80211_rtw_get_station(struct wiphy *wiphy,
2250
struct net_device *ndev,
2251
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
2252
u8 *mac,
2253
#else
2254
const u8 *mac,
2255
#endif
2256
struct station_info *sinfo)
2257
{
2258
int ret = 0;
2259
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2260
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2261
struct sta_info *psta = NULL;
2262
struct sta_priv *pstapriv = &padapter->stapriv;
2263
#ifdef CONFIG_RTW_MESH
2264
struct mesh_plink_ent *plink = NULL;
2265
#endif
2266
2267
sinfo->filled = 0;
2268
2269
if (!mac) {
2270
RTW_INFO(FUNC_NDEV_FMT" mac==%p\n", FUNC_NDEV_ARG(ndev), mac);
2271
ret = -ENOENT;
2272
goto exit;
2273
}
2274
2275
psta = rtw_get_stainfo(pstapriv, mac);
2276
#ifdef CONFIG_RTW_MESH
2277
if (MLME_IS_MESH(padapter)) {
2278
if (psta)
2279
plink = psta->plink;
2280
if (!plink)
2281
plink = rtw_mesh_plink_get(padapter, mac);
2282
}
2283
#endif /* CONFIG_RTW_MESH */
2284
2285
if ((!MLME_IS_MESH(padapter) && !psta)
2286
#ifdef CONFIG_RTW_MESH
2287
|| (MLME_IS_MESH(padapter) && !plink)
2288
#endif
2289
) {
2290
RTW_INFO(FUNC_NDEV_FMT" no sta info for mac="MAC_FMT"\n"
2291
, FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
2292
ret = -ENOENT;
2293
goto exit;
2294
}
2295
2296
#ifdef CONFIG_DEBUG_CFG80211
2297
RTW_INFO(FUNC_NDEV_FMT" mac="MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
2298
#endif
2299
2300
/* for infra./P2PClient mode */
2301
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)
2302
&& check_fwstate(pmlmepriv, _FW_LINKED)
2303
) {
2304
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2305
2306
if (_rtw_memcmp((u8 *)mac, cur_network->network.MacAddress, ETH_ALEN) == _FALSE) {
2307
RTW_INFO("%s, mismatch bssid="MAC_FMT"\n", __func__, MAC_ARG(cur_network->network.MacAddress));
2308
ret = -ENOENT;
2309
goto exit;
2310
}
2311
2312
sinfo->filled |= STATION_INFO_SIGNAL;
2313
sinfo->signal = translate_percentage_to_dbm(padapter->recvpriv.signal_strength);
2314
2315
sinfo->filled |= STATION_INFO_TX_BITRATE;
2316
sinfo->txrate.legacy = rtw_get_cur_max_rate(padapter);
2317
}
2318
2319
if (psta) {
2320
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _FALSE
2321
|| check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE
2322
) {
2323
sinfo->filled |= STATION_INFO_SIGNAL;
2324
sinfo->signal = translate_percentage_to_dbm(psta->cmn.rssi_stat.rssi);
2325
}
2326
sinfo->filled |= STATION_INFO_INACTIVE_TIME;
2327
sinfo->inactive_time = rtw_get_passing_time_ms(psta->sta_stats.last_rx_time);
2328
sinfo->filled |= STATION_INFO_RX_PACKETS;
2329
sinfo->rx_packets = sta_rx_data_pkts(psta);
2330
sinfo->filled |= STATION_INFO_TX_PACKETS;
2331
sinfo->tx_packets = psta->sta_stats.tx_pkts;
2332
sinfo->filled |= STATION_INFO_TX_FAILED;
2333
sinfo->tx_failed = psta->sta_stats.tx_fail_cnt;
2334
}
2335
2336
#ifdef CONFIG_RTW_MESH
2337
if (MLME_IS_MESH(padapter))
2338
rtw_cfg80211_fill_mesh_only_sta_info(plink, psta, sinfo);
2339
#endif
2340
2341
exit:
2342
return ret;
2343
}
2344
2345
extern int netdev_open(struct net_device *pnetdev);
2346
2347
#if 0
2348
enum nl80211_iftype {
2349
NL80211_IFTYPE_UNSPECIFIED,
2350
NL80211_IFTYPE_ADHOC, /* 1 */
2351
NL80211_IFTYPE_STATION, /* 2 */
2352
NL80211_IFTYPE_AP, /* 3 */
2353
NL80211_IFTYPE_AP_VLAN,
2354
NL80211_IFTYPE_WDS,
2355
NL80211_IFTYPE_MONITOR, /* 6 */
2356
NL80211_IFTYPE_MESH_POINT,
2357
NL80211_IFTYPE_P2P_CLIENT, /* 8 */
2358
NL80211_IFTYPE_P2P_GO, /* 9 */
2359
/* keep last */
2360
NUM_NL80211_IFTYPES,
2361
NL80211_IFTYPE_MAX = NUM_NL80211_IFTYPES - 1
2362
};
2363
#endif
2364
static int cfg80211_rtw_change_iface(struct wiphy *wiphy,
2365
struct net_device *ndev,
2366
enum nl80211_iftype type,
2367
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
2368
u32 *flags,
2369
#endif
2370
struct vif_params *params)
2371
{
2372
enum nl80211_iftype old_type;
2373
NDIS_802_11_NETWORK_INFRASTRUCTURE networkType;
2374
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
2375
struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
2376
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
2377
#ifdef CONFIG_P2P
2378
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2379
#endif
2380
#ifdef CONFIG_MONITOR_MODE_XMIT
2381
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2382
#endif
2383
int ret = 0;
2384
u8 change = _FALSE;
2385
2386
RTW_INFO(FUNC_NDEV_FMT" type=%d, hw_port:%d\n", FUNC_NDEV_ARG(ndev), type, padapter->hw_port);
2387
2388
if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
2389
ret = -EPERM;
2390
goto exit;
2391
}
2392
2393
2394
RTW_INFO(FUNC_NDEV_FMT" call netdev_open\n", FUNC_NDEV_ARG(ndev));
2395
if (netdev_open(ndev) != 0) {
2396
RTW_INFO(FUNC_NDEV_FMT" call netdev_open fail\n", FUNC_NDEV_ARG(ndev));
2397
ret = -EPERM;
2398
goto exit;
2399
}
2400
2401
2402
if (_FAIL == rtw_pwr_wakeup(padapter)) {
2403
RTW_INFO(FUNC_NDEV_FMT" call rtw_pwr_wakeup fail\n", FUNC_NDEV_ARG(ndev));
2404
ret = -EPERM;
2405
goto exit;
2406
}
2407
2408
old_type = rtw_wdev->iftype;
2409
RTW_INFO(FUNC_NDEV_FMT" old_iftype=%d, new_iftype=%d\n",
2410
FUNC_NDEV_ARG(ndev), old_type, type);
2411
2412
if (old_type != type) {
2413
change = _TRUE;
2414
pmlmeext->action_public_rxseq = 0xffff;
2415
pmlmeext->action_public_dialog_token = 0xff;
2416
}
2417
2418
/* initial default type */
2419
ndev->type = ARPHRD_ETHER;
2420
2421
/*
2422
* Disable Power Save in moniter mode,
2423
* and enable it after leaving moniter mode.
2424
*/
2425
if (type == NL80211_IFTYPE_MONITOR) {
2426
rtw_ps_deny(padapter, PS_DENY_MONITOR_MODE);
2427
LeaveAllPowerSaveMode(padapter);
2428
} else if (old_type == NL80211_IFTYPE_MONITOR) {
2429
/* driver in moniter mode in last time */
2430
rtw_ps_deny_cancel(padapter, PS_DENY_MONITOR_MODE);
2431
}
2432
2433
switch (type) {
2434
case NL80211_IFTYPE_ADHOC:
2435
networkType = Ndis802_11IBSS;
2436
break;
2437
2438
case NL80211_IFTYPE_STATION:
2439
networkType = Ndis802_11Infrastructure;
2440
#ifdef CONFIG_P2P
2441
if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
2442
#if !RTW_P2P_GROUP_INTERFACE
2443
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)
2444
|| rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
2445
) {
2446
/* it means remove GC/GO and change mode from GC/GO to station(P2P DEVICE) */
2447
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
2448
}
2449
#endif
2450
}
2451
#endif /* CONFIG_P2P */
2452
break;
2453
2454
case NL80211_IFTYPE_AP:
2455
networkType = Ndis802_11APMode;
2456
#ifdef CONFIG_P2P
2457
if (change && pwdinfo->driver_interface == DRIVER_CFG80211) {
2458
#if !RTW_P2P_GROUP_INTERFACE
2459
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
2460
/* it means P2P Group created, we will be GO and change mode from P2P DEVICE to AP(GO) */
2461
rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
2462
}
2463
#endif
2464
}
2465
#endif /* CONFIG_P2P */
2466
break;
2467
2468
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
2469
case NL80211_IFTYPE_P2P_CLIENT:
2470
networkType = Ndis802_11Infrastructure;
2471
if (change && pwdinfo->driver_interface == DRIVER_CFG80211)
2472
rtw_p2p_enable(padapter, P2P_ROLE_CLIENT);
2473
break;
2474
2475
case NL80211_IFTYPE_P2P_GO:
2476
networkType = Ndis802_11APMode;
2477
if (change && pwdinfo->driver_interface == DRIVER_CFG80211)
2478
rtw_p2p_enable(padapter, P2P_ROLE_GO);
2479
break;
2480
#endif /* defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)) */
2481
2482
#ifdef CONFIG_RTW_MESH
2483
case NL80211_IFTYPE_MESH_POINT:
2484
networkType = Ndis802_11_mesh;
2485
break;
2486
#endif
2487
2488
case NL80211_IFTYPE_MONITOR:
2489
networkType = Ndis802_11Monitor;
2490
#if 0
2491
ndev->type = ARPHRD_IEEE80211; /* IEEE 802.11 : 801 */
2492
#endif
2493
ndev->type = ARPHRD_IEEE80211_RADIOTAP; /* IEEE 802.11 + radiotap header : 803 */
2494
break;
2495
default:
2496
ret = -EOPNOTSUPP;
2497
goto exit;
2498
}
2499
2500
rtw_wdev->iftype = type;
2501
2502
if (rtw_set_802_11_infrastructure_mode(padapter, networkType, 0) == _FALSE) {
2503
rtw_wdev->iftype = old_type;
2504
ret = -EPERM;
2505
goto exit;
2506
}
2507
2508
rtw_setopmode_cmd(padapter, networkType, RTW_CMDF_WAIT_ACK);
2509
#ifdef CONFIG_MONITOR_MODE_XMIT
2510
if (check_fwstate(pmlmepriv, WIFI_MONITOR_STATE) == _TRUE)
2511
rtw_indicate_connect(padapter);
2512
#endif
2513
exit:
2514
2515
RTW_INFO(FUNC_NDEV_FMT" ret:%d\n", FUNC_NDEV_ARG(ndev), ret);
2516
return ret;
2517
}
2518
2519
void rtw_cfg80211_indicate_scan_done(_adapter *adapter, bool aborted)
2520
{
2521
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
2522
_irqL irqL;
2523
2524
#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE)
2525
struct cfg80211_scan_info info;
2526
2527
memset(&info, 0, sizeof(info));
2528
info.aborted = aborted;
2529
#endif
2530
2531
_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2532
if (pwdev_priv->scan_request != NULL) {
2533
#ifdef CONFIG_DEBUG_CFG80211
2534
RTW_INFO("%s with scan req\n", __FUNCTION__);
2535
#endif
2536
2537
/* avoid WARN_ON(request != wiphy_to_dev(request->wiphy)->scan_req); */
2538
if (pwdev_priv->scan_request->wiphy != pwdev_priv->rtw_wdev->wiphy)
2539
RTW_INFO("error wiphy compare\n");
2540
else
2541
#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE)
2542
cfg80211_scan_done(pwdev_priv->scan_request, &info);
2543
#else
2544
cfg80211_scan_done(pwdev_priv->scan_request, aborted);
2545
#endif
2546
2547
pwdev_priv->scan_request = NULL;
2548
} else {
2549
#ifdef CONFIG_DEBUG_CFG80211
2550
RTW_INFO("%s without scan req\n", __FUNCTION__);
2551
#endif
2552
}
2553
_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2554
}
2555
2556
u32 rtw_cfg80211_wait_scan_req_empty(_adapter *adapter, u32 timeout_ms)
2557
{
2558
struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
2559
u8 empty = _FALSE;
2560
systime start;
2561
u32 pass_ms;
2562
2563
start = rtw_get_current_time();
2564
2565
while (rtw_get_passing_time_ms(start) <= timeout_ms) {
2566
2567
if (RTW_CANNOT_RUN(adapter))
2568
break;
2569
2570
if (!wdev_priv->scan_request) {
2571
empty = _TRUE;
2572
break;
2573
}
2574
2575
rtw_msleep_os(10);
2576
}
2577
2578
pass_ms = rtw_get_passing_time_ms(start);
2579
2580
if (empty == _FALSE && pass_ms > timeout_ms)
2581
RTW_PRINT(FUNC_ADPT_FMT" pass_ms:%u, timeout\n"
2582
, FUNC_ADPT_ARG(adapter), pass_ms);
2583
2584
return pass_ms;
2585
}
2586
2587
void rtw_cfg80211_unlink_bss(_adapter *padapter, struct wlan_network *pnetwork)
2588
{
2589
struct wireless_dev *pwdev = padapter->rtw_wdev;
2590
struct wiphy *wiphy = pwdev->wiphy;
2591
struct cfg80211_bss *bss = NULL;
2592
WLAN_BSSID_EX select_network = pnetwork->network;
2593
2594
bss = cfg80211_get_bss(wiphy, NULL/*notify_channel*/,
2595
select_network.MacAddress, select_network.Ssid.Ssid,
2596
select_network.Ssid.SsidLength,
2597
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
2598
select_network.InfrastructureMode == Ndis802_11Infrastructure?IEEE80211_BSS_TYPE_ESS:IEEE80211_BSS_TYPE_IBSS,
2599
IEEE80211_PRIVACY(select_network.Privacy));
2600
#else
2601
select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS,
2602
select_network.InfrastructureMode == Ndis802_11Infrastructure?WLAN_CAPABILITY_ESS:WLAN_CAPABILITY_IBSS);
2603
#endif
2604
2605
if (bss) {
2606
cfg80211_unlink_bss(wiphy, bss);
2607
RTW_INFO("%s(): cfg80211_unlink %s!!\n", __func__, select_network.Ssid.Ssid);
2608
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)
2609
cfg80211_put_bss(padapter->rtw_wdev->wiphy, bss);
2610
#else
2611
cfg80211_put_bss(bss);
2612
#endif
2613
}
2614
return;
2615
}
2616
2617
/* if target wps scan ongoing, target_ssid is filled */
2618
int rtw_cfg80211_is_target_wps_scan(struct cfg80211_scan_request *scan_req, struct cfg80211_ssid *target_ssid)
2619
{
2620
int ret = 0;
2621
2622
if (scan_req->n_ssids != 1
2623
|| scan_req->ssids[0].ssid_len == 0
2624
|| scan_req->n_channels != 1
2625
)
2626
goto exit;
2627
2628
/* under target WPS scan */
2629
_rtw_memcpy(target_ssid, scan_req->ssids, sizeof(struct cfg80211_ssid));
2630
ret = 1;
2631
2632
exit:
2633
return ret;
2634
}
2635
2636
static void _rtw_cfg80211_surveydone_event_callback(_adapter *padapter, struct cfg80211_scan_request *scan_req)
2637
{
2638
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
2639
RT_CHANNEL_INFO *chset = rfctl->channel_set;
2640
_irqL irqL;
2641
_list *plist, *phead;
2642
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2643
_queue *queue = &(pmlmepriv->scanned_queue);
2644
struct wlan_network *pnetwork = NULL;
2645
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
2646
struct cfg80211_ssid target_ssid;
2647
u8 target_wps_scan = 0;
2648
u8 ch;
2649
2650
#ifdef CONFIG_DEBUG_CFG80211
2651
RTW_INFO("%s\n", __func__);
2652
#endif
2653
2654
if (scan_req)
2655
target_wps_scan = rtw_cfg80211_is_target_wps_scan(scan_req, &target_ssid);
2656
else {
2657
_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2658
if (pwdev_priv->scan_request != NULL)
2659
target_wps_scan = rtw_cfg80211_is_target_wps_scan(pwdev_priv->scan_request, &target_ssid);
2660
_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2661
}
2662
2663
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2664
2665
phead = get_list_head(queue);
2666
plist = get_next(phead);
2667
2668
while (1) {
2669
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
2670
break;
2671
2672
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
2673
ch = pnetwork->network.Configuration.DSConfig;
2674
2675
/* report network only if the current channel set contains the channel to which this network belongs */
2676
if (rtw_chset_search_ch(chset, ch) >= 0
2677
&& rtw_mlme_band_check(padapter, ch) == _TRUE
2678
&& _TRUE == rtw_validate_ssid(&(pnetwork->network.Ssid))
2679
&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
2680
|| rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl))
2681
|| !rtw_chset_is_ch_non_ocp(chset, ch))
2682
) {
2683
if (target_wps_scan)
2684
rtw_cfg80211_clear_wps_sr_of_non_target_bss(padapter, pnetwork, &target_ssid);
2685
rtw_cfg80211_inform_bss(padapter, pnetwork);
2686
}
2687
#if 0
2688
/* check ralink testbed RSN IE length */
2689
{
2690
if (_rtw_memcmp(pnetwork->network.Ssid.Ssid, "Ralink_11n_AP", 13)) {
2691
uint ie_len = 0;
2692
u8 *p = NULL;
2693
p = rtw_get_ie(pnetwork->network.IEs + _BEACON_IE_OFFSET_, _RSN_IE_2_, &ie_len, (pnetwork->network.IELength - _BEACON_IE_OFFSET_));
2694
RTW_INFO("ie_len=%d\n", ie_len);
2695
}
2696
}
2697
#endif
2698
plist = get_next(plist);
2699
2700
}
2701
2702
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
2703
}
2704
2705
inline void rtw_cfg80211_surveydone_event_callback(_adapter *padapter)
2706
{
2707
_rtw_cfg80211_surveydone_event_callback(padapter, NULL);
2708
}
2709
2710
static int rtw_cfg80211_set_probe_req_wpsp2pie(_adapter *padapter, char *buf, int len)
2711
{
2712
int ret = 0;
2713
uint wps_ielen = 0;
2714
u8 *wps_ie;
2715
u32 p2p_ielen = 0;
2716
u8 *p2p_ie;
2717
u32 wfd_ielen = 0;
2718
u8 *wfd_ie;
2719
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
2720
2721
#ifdef CONFIG_DEBUG_CFG80211
2722
RTW_INFO("%s, ielen=%d\n", __func__, len);
2723
#endif
2724
2725
if (len > 0) {
2726
wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
2727
if (wps_ie) {
2728
#ifdef CONFIG_DEBUG_CFG80211
2729
RTW_INFO("probe_req_wps_ielen=%d\n", wps_ielen);
2730
#endif
2731
2732
if (pmlmepriv->wps_probe_req_ie) {
2733
u32 free_len = pmlmepriv->wps_probe_req_ie_len;
2734
pmlmepriv->wps_probe_req_ie_len = 0;
2735
rtw_mfree(pmlmepriv->wps_probe_req_ie, free_len);
2736
pmlmepriv->wps_probe_req_ie = NULL;
2737
}
2738
2739
pmlmepriv->wps_probe_req_ie = rtw_malloc(wps_ielen);
2740
if (pmlmepriv->wps_probe_req_ie == NULL) {
2741
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2742
return -EINVAL;
2743
2744
}
2745
_rtw_memcpy(pmlmepriv->wps_probe_req_ie, wps_ie, wps_ielen);
2746
pmlmepriv->wps_probe_req_ie_len = wps_ielen;
2747
}
2748
2749
/* buf += wps_ielen; */
2750
/* len -= wps_ielen; */
2751
2752
#ifdef CONFIG_P2P
2753
p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
2754
if (p2p_ie) {
2755
struct wifidirect_info *wdinfo = &padapter->wdinfo;
2756
u32 attr_contentlen = 0;
2757
u8 listen_ch_attr[5];
2758
2759
#ifdef CONFIG_DEBUG_CFG80211
2760
RTW_INFO("probe_req_p2p_ielen=%d\n", p2p_ielen);
2761
#endif
2762
2763
if (pmlmepriv->p2p_probe_req_ie) {
2764
u32 free_len = pmlmepriv->p2p_probe_req_ie_len;
2765
pmlmepriv->p2p_probe_req_ie_len = 0;
2766
rtw_mfree(pmlmepriv->p2p_probe_req_ie, free_len);
2767
pmlmepriv->p2p_probe_req_ie = NULL;
2768
}
2769
2770
pmlmepriv->p2p_probe_req_ie = rtw_malloc(p2p_ielen);
2771
if (pmlmepriv->p2p_probe_req_ie == NULL) {
2772
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
2773
return -EINVAL;
2774
2775
}
2776
_rtw_memcpy(pmlmepriv->p2p_probe_req_ie, p2p_ie, p2p_ielen);
2777
pmlmepriv->p2p_probe_req_ie_len = p2p_ielen;
2778
2779
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, (u8 *)listen_ch_attr, (uint *) &attr_contentlen)
2780
&& attr_contentlen == 5) {
2781
if (wdinfo->listen_channel != listen_ch_attr[4]) {
2782
RTW_INFO(FUNC_ADPT_FMT" listen channel - country:%c%c%c, class:%u, ch:%u\n",
2783
FUNC_ADPT_ARG(padapter), listen_ch_attr[0], listen_ch_attr[1], listen_ch_attr[2],
2784
listen_ch_attr[3], listen_ch_attr[4]);
2785
wdinfo->listen_channel = listen_ch_attr[4];
2786
}
2787
}
2788
}
2789
#endif /* CONFIG_P2P */
2790
2791
#ifdef CONFIG_WFD
2792
wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
2793
if (wfd_ie) {
2794
#ifdef CONFIG_DEBUG_CFG80211
2795
RTW_INFO("probe_req_wfd_ielen=%d\n", wfd_ielen);
2796
#endif
2797
2798
if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
2799
return -EINVAL;
2800
}
2801
#endif /* CONFIG_WFD */
2802
}
2803
2804
return ret;
2805
2806
}
2807
2808
#ifdef CONFIG_CONCURRENT_MODE
2809
u8 rtw_cfg80211_scan_via_buddy(_adapter *padapter, struct cfg80211_scan_request *request)
2810
{
2811
int i;
2812
u8 ret = _FALSE;
2813
_adapter *iface = NULL;
2814
_irqL irqL;
2815
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2816
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
2817
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2818
2819
for (i = 0; i < dvobj->iface_nums; i++) {
2820
struct mlme_priv *buddy_mlmepriv;
2821
struct rtw_wdev_priv *buddy_wdev_priv;
2822
2823
iface = dvobj->padapters[i];
2824
if (iface == NULL)
2825
continue;
2826
2827
if (iface == padapter)
2828
continue;
2829
2830
if (rtw_is_adapter_up(iface) == _FALSE)
2831
continue;
2832
2833
buddy_mlmepriv = &iface->mlmepriv;
2834
if (!check_fwstate(buddy_mlmepriv, _FW_UNDER_SURVEY))
2835
continue;
2836
2837
buddy_wdev_priv = adapter_wdev_data(iface);
2838
_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2839
_enter_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
2840
if (buddy_wdev_priv->scan_request) {
2841
pmlmepriv->scanning_via_buddy_intf = _TRUE;
2842
_enter_critical_bh(&pmlmepriv->lock, &irqL);
2843
set_fwstate(pmlmepriv, _FW_UNDER_SURVEY);
2844
_exit_critical_bh(&pmlmepriv->lock, &irqL);
2845
pwdev_priv->scan_request = request;
2846
ret = _TRUE;
2847
}
2848
_exit_critical_bh(&buddy_wdev_priv->scan_req_lock, &irqL);
2849
_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
2850
2851
if (ret == _TRUE)
2852
goto exit;
2853
}
2854
2855
exit:
2856
return ret;
2857
}
2858
2859
void rtw_cfg80211_indicate_scan_done_for_buddy(_adapter *padapter, bool bscan_aborted)
2860
{
2861
int i;
2862
_adapter *iface = NULL;
2863
_irqL irqL;
2864
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
2865
struct mlme_priv *mlmepriv;
2866
struct rtw_wdev_priv *wdev_priv;
2867
bool indicate_buddy_scan;
2868
2869
for (i = 0; i < dvobj->iface_nums; i++) {
2870
iface = dvobj->padapters[i];
2871
if ((iface) && rtw_is_adapter_up(iface)) {
2872
2873
if (iface == padapter)
2874
continue;
2875
2876
mlmepriv = &(iface->mlmepriv);
2877
wdev_priv = adapter_wdev_data(iface);
2878
2879
indicate_buddy_scan = _FALSE;
2880
_enter_critical_bh(&wdev_priv->scan_req_lock, &irqL);
2881
if (mlmepriv->scanning_via_buddy_intf == _TRUE) {
2882
mlmepriv->scanning_via_buddy_intf = _FALSE;
2883
clr_fwstate(mlmepriv, _FW_UNDER_SURVEY);
2884
if (wdev_priv->scan_request)
2885
indicate_buddy_scan = _TRUE;
2886
}
2887
_exit_critical_bh(&wdev_priv->scan_req_lock, &irqL);
2888
2889
if (indicate_buddy_scan == _TRUE) {
2890
rtw_cfg80211_surveydone_event_callback(iface);
2891
rtw_indicate_scan_done(iface, bscan_aborted);
2892
}
2893
2894
}
2895
}
2896
}
2897
#endif /* CONFIG_CONCURRENT_MODE */
2898
2899
static int cfg80211_rtw_scan(struct wiphy *wiphy
2900
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2901
, struct net_device *ndev
2902
#endif
2903
, struct cfg80211_scan_request *request)
2904
{
2905
int i;
2906
u8 _status = _FALSE;
2907
int ret = 0;
2908
struct sitesurvey_parm parm;
2909
_irqL irqL;
2910
u8 survey_times = 3;
2911
u8 survey_times_for_one_ch = 6;
2912
struct cfg80211_ssid *ssids = request->ssids;
2913
int social_channel = 0, j = 0;
2914
bool need_indicate_scan_done = _FALSE;
2915
bool ps_denied = _FALSE;
2916
u8 ssc_chk;
2917
_adapter *padapter;
2918
struct wireless_dev *wdev;
2919
struct rtw_wdev_priv *pwdev_priv;
2920
struct mlme_priv *pmlmepriv = NULL;
2921
#ifdef CONFIG_P2P
2922
struct wifidirect_info *pwdinfo;
2923
#endif /* CONFIG_P2P */
2924
2925
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
2926
wdev = request->wdev;
2927
#if defined(RTW_DEDICATED_P2P_DEVICE)
2928
if (wdev == wiphy_to_pd_wdev(wiphy))
2929
padapter = wiphy_to_adapter(wiphy);
2930
else
2931
#endif
2932
if (wdev_to_ndev(wdev))
2933
padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
2934
else {
2935
ret = -EINVAL;
2936
goto exit;
2937
}
2938
#else
2939
if (ndev == NULL) {
2940
ret = -EINVAL;
2941
goto exit;
2942
}
2943
padapter = (_adapter *)rtw_netdev_priv(ndev);
2944
wdev = ndev_to_wdev(ndev);
2945
#endif
2946
2947
pwdev_priv = adapter_wdev_data(padapter);
2948
pmlmepriv = &padapter->mlmepriv;
2949
#ifdef CONFIG_P2P
2950
pwdinfo = &(padapter->wdinfo);
2951
#endif /* CONFIG_P2P */
2952
2953
RTW_INFO(FUNC_ADPT_FMT"%s\n", FUNC_ADPT_ARG(padapter)
2954
, wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : "");
2955
2956
#if 1
2957
ssc_chk = rtw_sitesurvey_condition_check(padapter, _TRUE);
2958
2959
if (ssc_chk == SS_DENY_MP_MODE)
2960
goto bypass_p2p_chk;
2961
#ifdef DBG_LA_MODE
2962
if (ssc_chk == SS_DENY_LA_MODE)
2963
goto bypass_p2p_chk;
2964
#endif
2965
#ifdef CONFIG_P2P
2966
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
2967
if (request->n_ssids && ssids
2968
&& _rtw_memcmp(ssids[0].ssid, "DIRECT-", 7)
2969
&& rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
2970
) {
2971
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
2972
rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
2973
else {
2974
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
2975
#ifdef CONFIG_DEBUG_CFG80211
2976
RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
2977
#endif
2978
}
2979
rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
2980
2981
if (request->n_channels == 3 &&
2982
request->channels[0]->hw_value == 1 &&
2983
request->channels[1]->hw_value == 6 &&
2984
request->channels[2]->hw_value == 11
2985
)
2986
social_channel = 1;
2987
}
2988
}
2989
#endif /*CONFIG_P2P*/
2990
2991
if (request->ie && request->ie_len > 0)
2992
rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
2993
2994
bypass_p2p_chk:
2995
2996
switch (ssc_chk) {
2997
case SS_ALLOW :
2998
break;
2999
3000
case SS_DENY_MP_MODE:
3001
ret = -EPERM;
3002
goto exit;
3003
#ifdef DBG_LA_MODE
3004
case SS_DENY_LA_MODE:
3005
ret = -EPERM;
3006
goto exit;
3007
#endif
3008
#ifdef CONFIG_RTW_REPEATER_SON
3009
case SS_DENY_RSON_SCANING :
3010
#endif
3011
case SS_DENY_BLOCK_SCAN :
3012
case SS_DENY_SELF_AP_UNDER_WPS :
3013
case SS_DENY_SELF_AP_UNDER_LINKING :
3014
case SS_DENY_SELF_AP_UNDER_SURVEY :
3015
case SS_DENY_SELF_STA_UNDER_SURVEY :
3016
#ifdef CONFIG_CONCURRENT_MODE
3017
case SS_DENY_BUDDY_UNDER_LINK_WPS :
3018
#endif
3019
case SS_DENY_BUSY_TRAFFIC :
3020
need_indicate_scan_done = _TRUE;
3021
goto check_need_indicate_scan_done;
3022
3023
case SS_DENY_BY_DRV :
3024
#if CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY
3025
ret = -EBUSY;
3026
goto exit;
3027
#else
3028
need_indicate_scan_done = _TRUE;
3029
goto check_need_indicate_scan_done;
3030
#endif
3031
break;
3032
3033
case SS_DENY_SELF_STA_UNDER_LINKING :
3034
ret = -EBUSY;
3035
goto check_need_indicate_scan_done;
3036
3037
#ifdef CONFIG_CONCURRENT_MODE
3038
case SS_DENY_BUDDY_UNDER_SURVEY :
3039
{
3040
bool scan_via_buddy = rtw_cfg80211_scan_via_buddy(padapter, request);
3041
3042
if (scan_via_buddy == _FALSE)
3043
need_indicate_scan_done = _TRUE;
3044
3045
goto check_need_indicate_scan_done;
3046
}
3047
#endif
3048
3049
default :
3050
RTW_ERR("site survey check code (%d) unknown\n", ssc_chk);
3051
need_indicate_scan_done = _TRUE;
3052
goto check_need_indicate_scan_done;
3053
}
3054
3055
rtw_ps_deny(padapter, PS_DENY_SCAN);
3056
ps_denied = _TRUE;
3057
if (_FAIL == rtw_pwr_wakeup(padapter)) {
3058
need_indicate_scan_done = _TRUE;
3059
goto check_need_indicate_scan_done;
3060
}
3061
3062
#else
3063
3064
3065
#ifdef CONFIG_MP_INCLUDED
3066
if (rtw_mp_mode_check(padapter)) {
3067
RTW_INFO("MP mode block Scan request\n");
3068
ret = -EPERM;
3069
goto exit;
3070
}
3071
#endif
3072
3073
#ifdef CONFIG_P2P
3074
if (pwdinfo->driver_interface == DRIVER_CFG80211) {
3075
if (request->n_ssids && ssids
3076
&& _rtw_memcmp(ssids[0].ssid, "DIRECT-", 7)
3077
&& rtw_get_p2p_ie((u8 *)request->ie, request->ie_len, NULL, NULL)
3078
) {
3079
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3080
rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
3081
else {
3082
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
3083
#ifdef CONFIG_DEBUG_CFG80211
3084
RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
3085
#endif
3086
}
3087
rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
3088
3089
if (request->n_channels == 3 &&
3090
request->channels[0]->hw_value == 1 &&
3091
request->channels[1]->hw_value == 6 &&
3092
request->channels[2]->hw_value == 11
3093
)
3094
social_channel = 1;
3095
}
3096
}
3097
#endif /*CONFIG_P2P*/
3098
3099
if (request->ie && request->ie_len > 0)
3100
rtw_cfg80211_set_probe_req_wpsp2pie(padapter, (u8 *)request->ie, request->ie_len);
3101
3102
#ifdef CONFIG_RTW_REPEATER_SON
3103
if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS) {
3104
RTW_INFO(FUNC_ADPT_FMT" blocking scan for under rson scanning process\n", FUNC_ADPT_ARG(padapter));
3105
need_indicate_scan_done = _TRUE;
3106
goto check_need_indicate_scan_done;
3107
}
3108
#endif
3109
3110
if (adapter_wdev_data(padapter)->block_scan == _TRUE) {
3111
RTW_INFO(FUNC_ADPT_FMT" wdev_priv.block_scan is set\n", FUNC_ADPT_ARG(padapter));
3112
need_indicate_scan_done = _TRUE;
3113
goto check_need_indicate_scan_done;
3114
}
3115
3116
rtw_ps_deny(padapter, PS_DENY_SCAN);
3117
ps_denied = _TRUE;
3118
if (_FAIL == rtw_pwr_wakeup(padapter)) {
3119
need_indicate_scan_done = _TRUE;
3120
goto check_need_indicate_scan_done;
3121
}
3122
3123
if (rtw_is_scan_deny(padapter)) {
3124
RTW_INFO(FUNC_ADPT_FMT ": scan deny\n", FUNC_ADPT_ARG(padapter));
3125
#if CONFIG_NOTIFY_SCAN_ABORT_WITH_BUSY
3126
ret = -EBUSY;
3127
goto exit;
3128
#else
3129
need_indicate_scan_done = _TRUE;
3130
goto check_need_indicate_scan_done;
3131
#endif
3132
}
3133
3134
/* check fw state*/
3135
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
3136
3137
#ifdef CONFIG_DEBUG_CFG80211
3138
RTW_INFO(FUNC_ADPT_FMT" under WIFI_AP_STATE\n", FUNC_ADPT_ARG(padapter));
3139
#endif
3140
3141
if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS | _FW_UNDER_SURVEY | _FW_UNDER_LINKING) == _TRUE) {
3142
RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
3143
3144
if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS))
3145
RTW_INFO("AP mode process WPS\n");
3146
3147
need_indicate_scan_done = _TRUE;
3148
goto check_need_indicate_scan_done;
3149
}
3150
}
3151
3152
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE) {
3153
RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
3154
need_indicate_scan_done = _TRUE;
3155
goto check_need_indicate_scan_done;
3156
} else if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
3157
RTW_INFO("%s, fwstate=0x%x\n", __func__, pmlmepriv->fw_state);
3158
ret = -EBUSY;
3159
goto check_need_indicate_scan_done;
3160
}
3161
3162
#ifdef CONFIG_CONCURRENT_MODE
3163
if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | WIFI_UNDER_WPS)) {
3164
RTW_INFO("%s exit due to buddy_intf's mlme state under linking or wps\n", __func__);
3165
need_indicate_scan_done = _TRUE;
3166
goto check_need_indicate_scan_done;
3167
3168
} else if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_SURVEY)) {
3169
bool scan_via_buddy = rtw_cfg80211_scan_via_buddy(padapter, request);
3170
3171
if (scan_via_buddy == _FALSE)
3172
need_indicate_scan_done = _TRUE;
3173
3174
goto check_need_indicate_scan_done;
3175
}
3176
#endif /* CONFIG_CONCURRENT_MODE */
3177
3178
/* busy traffic check*/
3179
if (rtw_mi_busy_traffic_check(padapter, _TRUE)) {
3180
need_indicate_scan_done = _TRUE;
3181
goto check_need_indicate_scan_done;
3182
}
3183
#endif
3184
3185
#ifdef CONFIG_P2P
3186
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
3187
rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH);
3188
3189
if (social_channel == 0)
3190
rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
3191
else
3192
rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_SOCIAL_LAST);
3193
}
3194
#endif /* CONFIG_P2P */
3195
3196
rtw_init_sitesurvey_parm(padapter, &parm);
3197
3198
/* parsing request ssids, n_ssids */
3199
for (i = 0; i < request->n_ssids && ssids && i < RTW_SSID_SCAN_AMOUNT; i++) {
3200
#ifdef CONFIG_DEBUG_CFG80211
3201
RTW_INFO("ssid=%s, len=%d\n", ssids[i].ssid, ssids[i].ssid_len);
3202
#endif
3203
_rtw_memcpy(&parm.ssid[i].Ssid, ssids[i].ssid, ssids[i].ssid_len);
3204
parm.ssid[i].SsidLength = ssids[i].ssid_len;
3205
}
3206
parm.ssid_num = i;
3207
3208
/* no ssid entry, set the scan type as passvie */
3209
if (request->n_ssids == 0)
3210
parm.scan_mode = SCAN_PASSIVE;
3211
3212
/* parsing channels, n_channels */
3213
for (i = 0; i < request->n_channels && i < RTW_CHANNEL_SCAN_AMOUNT; i++) {
3214
#ifdef CONFIG_DEBUG_CFG80211
3215
RTW_INFO(FUNC_ADPT_FMT CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(request->channels[i]));
3216
#endif
3217
parm.ch[i].hw_value = request->channels[i]->hw_value;
3218
parm.ch[i].flags = request->channels[i]->flags;
3219
}
3220
parm.ch_num = i;
3221
3222
if (request->n_channels == 1) {
3223
for (i = 1; i < survey_times_for_one_ch; i++)
3224
_rtw_memcpy(&parm.ch[i], &parm.ch[0], sizeof(struct rtw_ieee80211_channel));
3225
parm.ch_num = survey_times_for_one_ch;
3226
} else if (request->n_channels <= 4) {
3227
for (j = request->n_channels - 1; j >= 0; j--)
3228
for (i = 0; i < survey_times; i++)
3229
_rtw_memcpy(&parm.ch[j * survey_times + i], &parm.ch[j], sizeof(struct rtw_ieee80211_channel));
3230
parm.ch_num = survey_times * request->n_channels;
3231
}
3232
3233
_enter_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3234
_enter_critical_bh(&pmlmepriv->lock, &irqL);
3235
_status = rtw_sitesurvey_cmd(padapter, &parm);
3236
if (_status == _SUCCESS)
3237
pwdev_priv->scan_request = request;
3238
else
3239
ret = -1;
3240
_exit_critical_bh(&pmlmepriv->lock, &irqL);
3241
_exit_critical_bh(&pwdev_priv->scan_req_lock, &irqL);
3242
3243
check_need_indicate_scan_done:
3244
if (_TRUE == need_indicate_scan_done) {
3245
#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE)
3246
struct cfg80211_scan_info info;
3247
3248
memset(&info, 0, sizeof(info));
3249
info.aborted = 0;
3250
#endif
3251
3252
_rtw_cfg80211_surveydone_event_callback(padapter, request);
3253
#if (KERNEL_VERSION(4, 7, 0) <= LINUX_VERSION_CODE)
3254
cfg80211_scan_done(request, &info);
3255
#else
3256
cfg80211_scan_done(request, 0);
3257
#endif
3258
}
3259
3260
if (ps_denied == _TRUE)
3261
rtw_ps_deny_cancel(padapter, PS_DENY_SCAN);
3262
3263
exit:
3264
if (pmlmepriv)
3265
pmlmepriv->lastscantime = rtw_get_current_time();
3266
3267
return ret;
3268
}
3269
3270
static int cfg80211_rtw_set_wiphy_params(struct wiphy *wiphy, u32 changed)
3271
{
3272
#if 0
3273
struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
3274
3275
if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
3276
(iwm->conf.rts_threshold != wiphy->rts_threshold)) {
3277
int ret;
3278
3279
iwm->conf.rts_threshold = wiphy->rts_threshold;
3280
3281
ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
3282
CFG_RTS_THRESHOLD,
3283
iwm->conf.rts_threshold);
3284
if (ret < 0)
3285
return ret;
3286
}
3287
3288
if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
3289
(iwm->conf.frag_threshold != wiphy->frag_threshold)) {
3290
int ret;
3291
3292
iwm->conf.frag_threshold = wiphy->frag_threshold;
3293
3294
ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_FA_CFG_FIX,
3295
CFG_FRAG_THRESHOLD,
3296
iwm->conf.frag_threshold);
3297
if (ret < 0)
3298
return ret;
3299
}
3300
#endif
3301
RTW_INFO("%s\n", __func__);
3302
return 0;
3303
}
3304
3305
3306
3307
static int rtw_cfg80211_set_wpa_version(struct security_priv *psecuritypriv, u32 wpa_version)
3308
{
3309
RTW_INFO("%s, wpa_version=%d\n", __func__, wpa_version);
3310
3311
if (!wpa_version) {
3312
psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
3313
return 0;
3314
}
3315
3316
3317
if (wpa_version & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
3318
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPAPSK;
3319
3320
#if 0
3321
if (wpa_version & NL80211_WPA_VERSION_2)
3322
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK;
3323
#endif
3324
3325
#ifdef CONFIG_WAPI_SUPPORT
3326
if (wpa_version & NL80211_WAPI_VERSION_1)
3327
psecuritypriv->ndisauthtype = Ndis802_11AuthModeWAPI;
3328
#endif
3329
3330
return 0;
3331
3332
}
3333
3334
static int rtw_cfg80211_set_auth_type(struct security_priv *psecuritypriv,
3335
enum nl80211_auth_type sme_auth_type)
3336
{
3337
RTW_INFO("%s, nl80211_auth_type=%d\n", __func__, sme_auth_type);
3338
3339
psecuritypriv->auth_type = sme_auth_type;
3340
3341
if (sme_auth_type == NL80211_AUTHTYPE_SAE) {
3342
psecuritypriv->auth_alg = WLAN_AUTH_SAE;
3343
return 0;
3344
}
3345
3346
switch (sme_auth_type) {
3347
case NL80211_AUTHTYPE_AUTOMATIC:
3348
3349
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Auto;
3350
3351
break;
3352
case NL80211_AUTHTYPE_OPEN_SYSTEM:
3353
3354
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3355
3356
if (psecuritypriv->ndisauthtype > Ndis802_11AuthModeWPA)
3357
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3358
3359
#ifdef CONFIG_WAPI_SUPPORT
3360
if (psecuritypriv->ndisauthtype == Ndis802_11AuthModeWAPI)
3361
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3362
#endif
3363
3364
break;
3365
case NL80211_AUTHTYPE_SHARED_KEY:
3366
3367
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Shared;
3368
3369
psecuritypriv->ndisencryptstatus = Ndis802_11Encryption1Enabled;
3370
3371
3372
break;
3373
default:
3374
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open;
3375
/* return -ENOTSUPP; */
3376
}
3377
3378
return 0;
3379
3380
}
3381
3382
static int rtw_cfg80211_set_cipher(struct security_priv *psecuritypriv, u32 cipher, bool ucast)
3383
{
3384
u32 ndisencryptstatus = Ndis802_11EncryptionDisabled;
3385
3386
u32 *profile_cipher = ucast ? &psecuritypriv->dot11PrivacyAlgrthm :
3387
&psecuritypriv->dot118021XGrpPrivacy;
3388
3389
RTW_INFO("%s, ucast=%d, cipher=0x%x\n", __func__, ucast, cipher);
3390
3391
3392
if (!cipher) {
3393
*profile_cipher = _NO_PRIVACY_;
3394
psecuritypriv->ndisencryptstatus = ndisencryptstatus;
3395
return 0;
3396
}
3397
3398
switch (cipher) {
3399
case IW_AUTH_CIPHER_NONE:
3400
*profile_cipher = _NO_PRIVACY_;
3401
ndisencryptstatus = Ndis802_11EncryptionDisabled;
3402
#ifdef CONFIG_WAPI_SUPPORT
3403
if (psecuritypriv->dot11PrivacyAlgrthm == _SMS4_)
3404
*profile_cipher = _SMS4_;
3405
#endif
3406
break;
3407
case WLAN_CIPHER_SUITE_WEP40:
3408
*profile_cipher = _WEP40_;
3409
ndisencryptstatus = Ndis802_11Encryption1Enabled;
3410
break;
3411
case WLAN_CIPHER_SUITE_WEP104:
3412
*profile_cipher = _WEP104_;
3413
ndisencryptstatus = Ndis802_11Encryption1Enabled;
3414
break;
3415
case WLAN_CIPHER_SUITE_TKIP:
3416
*profile_cipher = _TKIP_;
3417
ndisencryptstatus = Ndis802_11Encryption2Enabled;
3418
break;
3419
case WLAN_CIPHER_SUITE_CCMP:
3420
*profile_cipher = _AES_;
3421
ndisencryptstatus = Ndis802_11Encryption3Enabled;
3422
break;
3423
#ifdef CONFIG_WAPI_SUPPORT
3424
case WLAN_CIPHER_SUITE_SMS4:
3425
*profile_cipher = _SMS4_;
3426
ndisencryptstatus = Ndis802_11_EncrypteionWAPI;
3427
break;
3428
#endif
3429
default:
3430
RTW_INFO("Unsupported cipher: 0x%x\n", cipher);
3431
return -ENOTSUPP;
3432
}
3433
3434
if (ucast) {
3435
psecuritypriv->ndisencryptstatus = ndisencryptstatus;
3436
3437
/* if(psecuritypriv->dot11PrivacyAlgrthm >= _AES_) */
3438
/* psecuritypriv->ndisauthtype = Ndis802_11AuthModeWPA2PSK; */
3439
}
3440
3441
return 0;
3442
}
3443
3444
static int rtw_cfg80211_set_key_mgt(struct security_priv *psecuritypriv, u32 key_mgt)
3445
{
3446
RTW_INFO("%s, key_mgt=0x%x\n", __func__, key_mgt);
3447
3448
if (key_mgt == WLAN_AKM_SUITE_8021X) {
3449
/* *auth_type = UMAC_AUTH_TYPE_8021X; */
3450
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3451
psecuritypriv->rsn_akm_suite_type = 1;
3452
} else if (key_mgt == WLAN_AKM_SUITE_PSK) {
3453
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3454
psecuritypriv->rsn_akm_suite_type = 2;
3455
}
3456
#ifdef CONFIG_WAPI_SUPPORT
3457
else if (key_mgt == WLAN_AKM_SUITE_WAPI_PSK)
3458
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3459
else if (key_mgt == WLAN_AKM_SUITE_WAPI_CERT)
3460
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_WAPI;
3461
#endif
3462
#ifdef CONFIG_RTW_80211R
3463
else if (key_mgt == WLAN_AKM_SUITE_FT_8021X) {
3464
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3465
psecuritypriv->rsn_akm_suite_type = 3;
3466
} else if (key_mgt == WLAN_AKM_SUITE_FT_PSK) {
3467
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3468
psecuritypriv->rsn_akm_suite_type = 4;
3469
}
3470
#endif
3471
else {
3472
RTW_INFO("Invalid key mgt: 0x%x\n", key_mgt);
3473
/* return -EINVAL; */
3474
}
3475
3476
return 0;
3477
}
3478
3479
static int rtw_cfg80211_set_wpa_ie(_adapter *padapter, u8 *pie, size_t ielen)
3480
{
3481
u8 *buf = NULL, *pos = NULL;
3482
int group_cipher = 0, pairwise_cipher = 0;
3483
u8 mfp_opt = MFP_NO;
3484
int ret = 0;
3485
int wpa_ielen = 0;
3486
int wpa2_ielen = 0;
3487
u8 *pwpa, *pwpa2;
3488
u8 null_addr[] = {0, 0, 0, 0, 0, 0};
3489
3490
if (pie == NULL || !ielen) {
3491
/* Treat this as normal case, but need to clear WIFI_UNDER_WPS */
3492
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
3493
goto exit;
3494
}
3495
3496
if (ielen > MAX_WPA_IE_LEN + MAX_WPS_IE_LEN + MAX_P2P_IE_LEN) {
3497
ret = -EINVAL;
3498
goto exit;
3499
}
3500
3501
buf = rtw_zmalloc(ielen);
3502
if (buf == NULL) {
3503
ret = -ENOMEM;
3504
goto exit;
3505
}
3506
3507
_rtw_memcpy(buf, pie , ielen);
3508
3509
RTW_INFO("set wpa_ie(length:%zu):\n", ielen);
3510
RTW_INFO_DUMP(NULL, buf, ielen);
3511
3512
pos = buf;
3513
if (ielen < RSN_HEADER_LEN) {
3514
ret = -1;
3515
goto exit;
3516
}
3517
3518
pwpa = rtw_get_wpa_ie(buf, &wpa_ielen, ielen);
3519
if (pwpa && wpa_ielen > 0) {
3520
if (rtw_parse_wpa_ie(pwpa, wpa_ielen + 2, &group_cipher, &pairwise_cipher, NULL) == _SUCCESS) {
3521
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3522
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPAPSK;
3523
_rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa[0], wpa_ielen + 2);
3524
3525
RTW_INFO("got wpa_ie, wpa_ielen:%u\n", wpa_ielen);
3526
}
3527
}
3528
3529
pwpa2 = rtw_get_wpa2_ie(buf, &wpa2_ielen, ielen);
3530
if (pwpa2 && wpa2_ielen > 0) {
3531
if (rtw_parse_wpa2_ie(pwpa2, wpa2_ielen + 2, &group_cipher, &pairwise_cipher, NULL, &mfp_opt) == _SUCCESS) {
3532
padapter->securitypriv.dot11AuthAlgrthm = dot11AuthAlgrthm_8021X;
3533
padapter->securitypriv.ndisauthtype = Ndis802_11AuthModeWPA2PSK;
3534
_rtw_memcpy(padapter->securitypriv.supplicant_ie, &pwpa2[0], wpa2_ielen + 2);
3535
3536
RTW_INFO("got wpa2_ie, wpa2_ielen:%u\n", wpa2_ielen);
3537
}
3538
}
3539
3540
if (group_cipher == 0)
3541
group_cipher = WPA_CIPHER_NONE;
3542
if (pairwise_cipher == 0)
3543
pairwise_cipher = WPA_CIPHER_NONE;
3544
3545
switch (group_cipher) {
3546
case WPA_CIPHER_NONE:
3547
padapter->securitypriv.dot118021XGrpPrivacy = _NO_PRIVACY_;
3548
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3549
break;
3550
case WPA_CIPHER_WEP40:
3551
padapter->securitypriv.dot118021XGrpPrivacy = _WEP40_;
3552
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3553
break;
3554
case WPA_CIPHER_TKIP:
3555
padapter->securitypriv.dot118021XGrpPrivacy = _TKIP_;
3556
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
3557
break;
3558
case WPA_CIPHER_CCMP:
3559
padapter->securitypriv.dot118021XGrpPrivacy = _AES_;
3560
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
3561
break;
3562
case WPA_CIPHER_WEP104:
3563
padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
3564
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3565
break;
3566
}
3567
3568
switch (pairwise_cipher) {
3569
case WPA_CIPHER_NONE:
3570
padapter->securitypriv.dot11PrivacyAlgrthm = _NO_PRIVACY_;
3571
padapter->securitypriv.ndisencryptstatus = Ndis802_11EncryptionDisabled;
3572
break;
3573
case WPA_CIPHER_WEP40:
3574
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP40_;
3575
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3576
break;
3577
case WPA_CIPHER_TKIP:
3578
padapter->securitypriv.dot11PrivacyAlgrthm = _TKIP_;
3579
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption2Enabled;
3580
break;
3581
case WPA_CIPHER_CCMP:
3582
padapter->securitypriv.dot11PrivacyAlgrthm = _AES_;
3583
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption3Enabled;
3584
break;
3585
case WPA_CIPHER_WEP104:
3586
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
3587
padapter->securitypriv.ndisencryptstatus = Ndis802_11Encryption1Enabled;
3588
break;
3589
}
3590
3591
if (mfp_opt == MFP_INVALID) {
3592
RTW_INFO(FUNC_ADPT_FMT" invalid MFP setting\n", FUNC_ADPT_ARG(padapter));
3593
ret = -EINVAL;
3594
goto exit;
3595
}
3596
padapter->securitypriv.mfp_opt = mfp_opt;
3597
3598
{/* handle wps_ie */
3599
uint wps_ielen;
3600
u8 *wps_ie;
3601
3602
wps_ie = rtw_get_wps_ie(buf, ielen, NULL, &wps_ielen);
3603
if (wps_ie && wps_ielen > 0) {
3604
RTW_INFO("got wps_ie, wps_ielen:%u\n", wps_ielen);
3605
padapter->securitypriv.wps_ie_len = wps_ielen < MAX_WPS_IE_LEN ? wps_ielen : MAX_WPS_IE_LEN;
3606
_rtw_memcpy(padapter->securitypriv.wps_ie, wps_ie, padapter->securitypriv.wps_ie_len);
3607
set_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS);
3608
} else
3609
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
3610
}
3611
3612
#ifdef CONFIG_P2P
3613
{/* check p2p_ie for assoc req; */
3614
uint p2p_ielen = 0;
3615
u8 *p2p_ie;
3616
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3617
3618
p2p_ie = rtw_get_p2p_ie(buf, ielen, NULL, &p2p_ielen);
3619
if (p2p_ie) {
3620
#ifdef CONFIG_DEBUG_CFG80211
3621
RTW_INFO("%s p2p_assoc_req_ielen=%d\n", __FUNCTION__, p2p_ielen);
3622
#endif
3623
3624
if (pmlmepriv->p2p_assoc_req_ie) {
3625
u32 free_len = pmlmepriv->p2p_assoc_req_ie_len;
3626
pmlmepriv->p2p_assoc_req_ie_len = 0;
3627
rtw_mfree(pmlmepriv->p2p_assoc_req_ie, free_len);
3628
pmlmepriv->p2p_assoc_req_ie = NULL;
3629
}
3630
3631
pmlmepriv->p2p_assoc_req_ie = rtw_malloc(p2p_ielen);
3632
if (pmlmepriv->p2p_assoc_req_ie == NULL) {
3633
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
3634
goto exit;
3635
}
3636
_rtw_memcpy(pmlmepriv->p2p_assoc_req_ie, p2p_ie, p2p_ielen);
3637
pmlmepriv->p2p_assoc_req_ie_len = p2p_ielen;
3638
}
3639
}
3640
#endif /* CONFIG_P2P */
3641
3642
#ifdef CONFIG_WFD
3643
{
3644
uint wfd_ielen = 0;
3645
u8 *wfd_ie;
3646
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3647
3648
wfd_ie = rtw_get_wfd_ie(buf, ielen, NULL, &wfd_ielen);
3649
if (wfd_ie) {
3650
#ifdef CONFIG_DEBUG_CFG80211
3651
RTW_INFO("%s wfd_assoc_req_ielen=%d\n", __FUNCTION__, wfd_ielen);
3652
#endif
3653
3654
if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_REQ_IE, wfd_ie, wfd_ielen) != _SUCCESS)
3655
goto exit;
3656
}
3657
}
3658
#endif /* CONFIG_WFD */
3659
3660
/* TKIP and AES disallow multicast packets until installing group key */
3661
if (padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_
3662
|| padapter->securitypriv.dot11PrivacyAlgrthm == _TKIP_WTMIC_
3663
|| padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)
3664
/* WPS open need to enable multicast */
3665
/* || check_fwstate(&padapter->mlmepriv, WIFI_UNDER_WPS) == _TRUE) */
3666
rtw_hal_set_hwreg(padapter, HW_VAR_OFF_RCR_AM, null_addr);
3667
3668
3669
exit:
3670
if (buf)
3671
rtw_mfree(buf, ielen);
3672
if (ret)
3673
_clr_fwstate_(&padapter->mlmepriv, WIFI_UNDER_WPS);
3674
3675
return ret;
3676
}
3677
3678
static int cfg80211_rtw_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
3679
struct cfg80211_ibss_params *params)
3680
{
3681
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3682
NDIS_802_11_SSID ndis_ssid;
3683
struct security_priv *psecuritypriv = &padapter->securitypriv;
3684
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3685
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
3686
struct cfg80211_chan_def *pch_def;
3687
#endif
3688
struct ieee80211_channel *pch;
3689
int ret = 0;
3690
3691
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
3692
pch_def = (struct cfg80211_chan_def *)(&params->chandef);
3693
pch = (struct ieee80211_channel *) pch_def->chan;
3694
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
3695
pch = (struct ieee80211_channel *)(params->channel);
3696
#endif
3697
3698
if (!params->ssid || !params->ssid_len) {
3699
ret = -EINVAL;
3700
goto exit;
3701
}
3702
3703
if (params->ssid_len > IW_ESSID_MAX_SIZE) {
3704
ret = -E2BIG;
3705
goto exit;
3706
}
3707
3708
rtw_ps_deny(padapter, PS_DENY_JOIN);
3709
if (_FAIL == rtw_pwr_wakeup(padapter)) {
3710
ret = -EPERM;
3711
goto cancel_ps_deny;
3712
}
3713
3714
#ifdef CONFIG_CONCURRENT_MODE
3715
if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING)) {
3716
RTW_INFO("%s, but buddy_intf is under linking\n", __FUNCTION__);
3717
ret = -EINVAL;
3718
goto cancel_ps_deny;
3719
}
3720
rtw_mi_buddy_scan_abort(padapter, _TRUE); /* OR rtw_mi_scan_abort(padapter, _TRUE);*/
3721
#endif /*CONFIG_CONCURRENT_MODE*/
3722
3723
3724
_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
3725
ndis_ssid.SsidLength = params->ssid_len;
3726
_rtw_memcpy(ndis_ssid.Ssid, (u8 *)params->ssid, params->ssid_len);
3727
3728
/* RTW_INFO("ssid=%s, len=%zu\n", ndis_ssid.Ssid, params->ssid_len); */
3729
3730
psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
3731
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
3732
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3733
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3734
psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
3735
3736
ret = rtw_cfg80211_set_auth_type(psecuritypriv, NL80211_AUTHTYPE_OPEN_SYSTEM);
3737
rtw_set_802_11_authentication_mode(padapter, psecuritypriv->ndisauthtype);
3738
3739
RTW_INFO("%s: center_freq = %d\n", __func__, pch->center_freq);
3740
pmlmeext->cur_channel = rtw_freq2ch(pch->center_freq);
3741
3742
if (rtw_set_802_11_ssid(padapter, &ndis_ssid) == _FALSE) {
3743
ret = -1;
3744
goto cancel_ps_deny;
3745
}
3746
3747
cancel_ps_deny:
3748
rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
3749
exit:
3750
return ret;
3751
}
3752
3753
static int cfg80211_rtw_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
3754
{
3755
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3756
struct wireless_dev *rtw_wdev = padapter->rtw_wdev;
3757
enum nl80211_iftype old_type;
3758
int ret = 0;
3759
3760
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
3761
3762
#if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
3763
rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 1);
3764
#endif
3765
3766
old_type = rtw_wdev->iftype;
3767
3768
rtw_set_to_roam(padapter, 0);
3769
3770
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
3771
rtw_scan_abort(padapter);
3772
LeaveAllPowerSaveMode(padapter);
3773
3774
rtw_wdev->iftype = NL80211_IFTYPE_STATION;
3775
3776
if (rtw_set_802_11_infrastructure_mode(padapter, Ndis802_11Infrastructure, 0) == _FALSE) {
3777
rtw_wdev->iftype = old_type;
3778
ret = -EPERM;
3779
goto leave_ibss;
3780
}
3781
rtw_setopmode_cmd(padapter, Ndis802_11Infrastructure, RTW_CMDF_WAIT_ACK);
3782
}
3783
3784
leave_ibss:
3785
#if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
3786
rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 0);
3787
#endif
3788
3789
return 0;
3790
}
3791
3792
bool rtw_cfg80211_is_connect_requested(_adapter *adapter)
3793
{
3794
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
3795
_irqL irqL;
3796
bool requested;
3797
3798
_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
3799
requested = pwdev_priv->connect_req ? 1 : 0;
3800
_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
3801
3802
return requested;
3803
}
3804
3805
static int _rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev)
3806
{
3807
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3808
3809
3810
/* if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) */
3811
{
3812
rtw_scan_abort(padapter);
3813
rtw_join_abort_timeout(padapter, 300);
3814
LeaveAllPowerSaveMode(padapter);
3815
rtw_disassoc_cmd(padapter, 500, RTW_CMDF_WAIT_ACK);
3816
#ifdef CONFIG_RTW_REPEATER_SON
3817
rtw_rson_do_disconnect(padapter);
3818
#endif
3819
RTW_INFO("%s...call rtw_indicate_disconnect\n", __func__);
3820
3821
rtw_free_assoc_resources_cmd(padapter, _TRUE, RTW_CMDF_WAIT_ACK);
3822
3823
/* indicate locally_generated = 0 when suspend */
3824
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0))
3825
rtw_indicate_disconnect(padapter, 0, wiphy->dev.power.is_prepared ? _FALSE : _TRUE);
3826
#else
3827
/*
3828
* for kernel < 4.2, DISCONNECT event is hardcoded with
3829
* NL80211_ATTR_DISCONNECTED_BY_AP=1 in NL80211 layer
3830
* no need to judge if under suspend
3831
*/
3832
rtw_indicate_disconnect(padapter, 0, _TRUE);
3833
#endif
3834
3835
rtw_pwr_wakeup(padapter);
3836
}
3837
return 0;
3838
}
3839
3840
#if (KERNEL_VERSION(4, 17, 0) > LINUX_VERSION_CODE)
3841
static bool rtw_check_connect_sae_compat(struct cfg80211_connect_params *sme)
3842
{
3843
struct rtw_ieee802_11_elems elems;
3844
struct rsne_info info;
3845
u8 AKM_SUITE_SAE[] = { 0x00, 0x0f, 0xac, 8 };
3846
int i;
3847
3848
if (sme->auth_type != 1)
3849
return false;
3850
3851
if (rtw_ieee802_11_parse_elems((u8 *)sme->ie, sme->ie_len, &elems, 0)
3852
== ParseFailed)
3853
return false;
3854
3855
if (!elems.rsn_ie)
3856
return false;
3857
3858
if (rtw_rsne_info_parse(elems.rsn_ie - 2, elems.rsn_ie_len + 2, &info) == _FAIL)
3859
return false;
3860
3861
for (i = 0; i < info.akm_cnt; i++)
3862
if (memcmp(info.akm_list + i * RSN_SELECTOR_LEN,
3863
AKM_SUITE_SAE, RSN_SELECTOR_LEN) == 0)
3864
return true;
3865
3866
return false;
3867
}
3868
#else
3869
#define rtw_check_connect_sae_compat(sme) false
3870
#endif
3871
3872
static int cfg80211_rtw_connect(struct wiphy *wiphy, struct net_device *ndev,
3873
struct cfg80211_connect_params *sme)
3874
{
3875
int ret = 0;
3876
NDIS_802_11_AUTHENTICATION_MODE authmode;
3877
NDIS_802_11_SSID ndis_ssid;
3878
/* u8 matched_by_bssid=_FALSE; */
3879
/* u8 matched_by_ssid=_FALSE; */
3880
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
3881
struct security_priv *psecuritypriv = &padapter->securitypriv;
3882
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
3883
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3884
_irqL irqL;
3885
3886
#if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_CONNECT)
3887
rtw_wdev_set_not_indic_disco(pwdev_priv, 1);
3888
#endif
3889
3890
RTW_INFO("=>"FUNC_NDEV_FMT" - Start to Connection\n", FUNC_NDEV_ARG(ndev));
3891
RTW_INFO("privacy=%d, key=%p, key_len=%d, key_idx=%d, auth_type=%d\n",
3892
sme->privacy, sme->key, sme->key_len, sme->key_idx, sme->auth_type);
3893
3894
if (rtw_check_connect_sae_compat(sme)) {
3895
sme->auth_type = NL80211_AUTHTYPE_SAE;
3896
RTW_INFO("%s set sme->auth_type=%d for SAE compat\n", __FUNCTION__,
3897
NL80211_AUTHTYPE_SAE);
3898
}
3899
3900
if (pwdev_priv->block == _TRUE) {
3901
ret = -EBUSY;
3902
RTW_INFO("%s wdev_priv.block is set\n", __FUNCTION__);
3903
goto exit;
3904
}
3905
3906
if (check_fwstate(pmlmepriv, _FW_LINKED | _FW_UNDER_LINKING) == _TRUE) {
3907
3908
_rtw_disconnect(wiphy, ndev);
3909
RTW_INFO("%s disconnect before connecting! fw_state=0x%x\n",
3910
__FUNCTION__, pmlmepriv->fw_state);
3911
}
3912
3913
#ifdef CONFIG_PLATFORM_MSTAR_SCAN_BEFORE_CONNECT
3914
printk("MStar Android!\n");
3915
if (pwdev_priv->bandroid_scan == _FALSE) {
3916
#ifdef CONFIG_P2P
3917
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3918
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
3919
#endif /* CONFIG_P2P */
3920
{
3921
ret = -EBUSY;
3922
printk("Android hasn't attached yet!\n");
3923
goto exit;
3924
}
3925
}
3926
#endif
3927
3928
if (!sme->ssid || !sme->ssid_len) {
3929
ret = -EINVAL;
3930
goto exit;
3931
}
3932
3933
if (sme->ssid_len > IW_ESSID_MAX_SIZE) {
3934
ret = -E2BIG;
3935
goto exit;
3936
}
3937
3938
rtw_ps_deny(padapter, PS_DENY_JOIN);
3939
if (_FAIL == rtw_pwr_wakeup(padapter)) {
3940
ret = -EPERM;
3941
goto cancel_ps_deny;
3942
}
3943
3944
rtw_mi_scan_abort(padapter, _TRUE);
3945
3946
rtw_join_abort_timeout(padapter, 300);
3947
#ifdef CONFIG_CONCURRENT_MODE
3948
if (rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING)) {
3949
ret = -EINVAL;
3950
goto cancel_ps_deny;
3951
}
3952
#endif
3953
3954
_rtw_memset(&ndis_ssid, 0, sizeof(NDIS_802_11_SSID));
3955
ndis_ssid.SsidLength = sme->ssid_len;
3956
_rtw_memcpy(ndis_ssid.Ssid, (u8 *)sme->ssid, sme->ssid_len);
3957
3958
RTW_INFO("ssid=%s, len=%zu\n", ndis_ssid.Ssid, sme->ssid_len);
3959
3960
3961
if (sme->bssid)
3962
RTW_INFO("bssid="MAC_FMT"\n", MAC_ARG(sme->bssid));
3963
3964
3965
psecuritypriv->ndisencryptstatus = Ndis802_11EncryptionDisabled;
3966
psecuritypriv->dot11PrivacyAlgrthm = _NO_PRIVACY_;
3967
psecuritypriv->dot118021XGrpPrivacy = _NO_PRIVACY_;
3968
psecuritypriv->dot11AuthAlgrthm = dot11AuthAlgrthm_Open; /* open system */
3969
psecuritypriv->ndisauthtype = Ndis802_11AuthModeOpen;
3970
psecuritypriv->auth_alg = WLAN_AUTH_OPEN;
3971
psecuritypriv->extauth_status = WLAN_STATUS_UNSPECIFIED_FAILURE;
3972
3973
#ifdef CONFIG_WAPI_SUPPORT
3974
padapter->wapiInfo.bWapiEnable = false;
3975
#endif
3976
3977
ret = rtw_cfg80211_set_wpa_version(psecuritypriv, sme->crypto.wpa_versions);
3978
if (ret < 0)
3979
goto cancel_ps_deny;
3980
3981
#ifdef CONFIG_WAPI_SUPPORT
3982
if (sme->crypto.wpa_versions & NL80211_WAPI_VERSION_1) {
3983
padapter->wapiInfo.bWapiEnable = true;
3984
padapter->wapiInfo.extra_prefix_len = WAPI_EXT_LEN;
3985
padapter->wapiInfo.extra_postfix_len = SMS4_MIC_LEN;
3986
}
3987
#endif
3988
3989
ret = rtw_cfg80211_set_auth_type(psecuritypriv, sme->auth_type);
3990
3991
#ifdef CONFIG_WAPI_SUPPORT
3992
if (psecuritypriv->dot11AuthAlgrthm == dot11AuthAlgrthm_WAPI)
3993
padapter->mlmeextpriv.mlmext_info.auth_algo = psecuritypriv->dot11AuthAlgrthm;
3994
#endif
3995
3996
3997
if (ret < 0)
3998
goto cancel_ps_deny;
3999
4000
RTW_INFO("%s, ie_len=%zu\n", __func__, sme->ie_len);
4001
4002
ret = rtw_cfg80211_set_wpa_ie(padapter, (u8 *)sme->ie, sme->ie_len);
4003
if (ret < 0)
4004
goto cancel_ps_deny;
4005
4006
if (sme->crypto.n_ciphers_pairwise) {
4007
ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.ciphers_pairwise[0], _TRUE);
4008
if (ret < 0)
4009
goto cancel_ps_deny;
4010
}
4011
4012
/* For WEP Shared auth */
4013
if (sme->key_len > 0 && sme->key) {
4014
u32 wep_key_idx, wep_key_len, wep_total_len;
4015
NDIS_802_11_WEP *pwep = NULL;
4016
RTW_INFO("%s(): Shared/Auto WEP\n", __FUNCTION__);
4017
4018
wep_key_idx = sme->key_idx;
4019
wep_key_len = sme->key_len;
4020
4021
if (sme->key_idx > WEP_KEYS) {
4022
ret = -EINVAL;
4023
goto cancel_ps_deny;
4024
}
4025
4026
if (wep_key_len > 0) {
4027
wep_key_len = wep_key_len <= 5 ? 5 : 13;
4028
wep_total_len = wep_key_len + FIELD_OFFSET(NDIS_802_11_WEP, KeyMaterial);
4029
pwep = (NDIS_802_11_WEP *) rtw_malloc(wep_total_len);
4030
if (pwep == NULL) {
4031
RTW_INFO(" wpa_set_encryption: pwep allocate fail !!!\n");
4032
ret = -ENOMEM;
4033
goto cancel_ps_deny;
4034
}
4035
4036
_rtw_memset(pwep, 0, wep_total_len);
4037
4038
pwep->KeyLength = wep_key_len;
4039
pwep->Length = wep_total_len;
4040
4041
if (wep_key_len == 13) {
4042
padapter->securitypriv.dot11PrivacyAlgrthm = _WEP104_;
4043
padapter->securitypriv.dot118021XGrpPrivacy = _WEP104_;
4044
}
4045
} else {
4046
ret = -EINVAL;
4047
goto cancel_ps_deny;
4048
}
4049
4050
pwep->KeyIndex = wep_key_idx;
4051
pwep->KeyIndex |= 0x80000000;
4052
4053
_rtw_memcpy(pwep->KeyMaterial, (void *)sme->key, pwep->KeyLength);
4054
4055
if (rtw_set_802_11_add_wep(padapter, pwep) == (u8)_FAIL)
4056
ret = -EOPNOTSUPP ;
4057
4058
if (pwep)
4059
rtw_mfree((u8 *)pwep, wep_total_len);
4060
4061
if (ret < 0)
4062
goto cancel_ps_deny;
4063
}
4064
4065
ret = rtw_cfg80211_set_cipher(psecuritypriv, sme->crypto.cipher_group, _FALSE);
4066
if (ret < 0)
4067
return ret;
4068
4069
if (sme->crypto.n_akm_suites) {
4070
ret = rtw_cfg80211_set_key_mgt(psecuritypriv, sme->crypto.akm_suites[0]);
4071
if (ret < 0)
4072
goto cancel_ps_deny;
4073
}
4074
#ifdef CONFIG_8011R
4075
else {
4076
/*It could be a connection without RSN IEs*/
4077
psecuritypriv->rsn_akm_suite_type = 0;
4078
}
4079
#endif
4080
4081
#ifdef CONFIG_WAPI_SUPPORT
4082
if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_PSK)
4083
padapter->wapiInfo.bWapiPSK = true;
4084
else if (sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_WAPI_CERT)
4085
padapter->wapiInfo.bWapiPSK = false;
4086
#endif
4087
4088
authmode = psecuritypriv->ndisauthtype;
4089
rtw_set_802_11_authentication_mode(padapter, authmode);
4090
4091
/* rtw_set_802_11_encryption_mode(padapter, padapter->securitypriv.ndisencryptstatus); */
4092
4093
if (rtw_set_802_11_connect(padapter, (u8 *)sme->bssid, &ndis_ssid) == _FALSE) {
4094
ret = -1;
4095
goto cancel_ps_deny;
4096
}
4097
4098
4099
_enter_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
4100
4101
if (pwdev_priv->connect_req) {
4102
rtw_wdev_free_connect_req(pwdev_priv);
4103
RTW_INFO(FUNC_NDEV_FMT" free existing connect_req\n", FUNC_NDEV_ARG(ndev));
4104
}
4105
4106
pwdev_priv->connect_req = (struct cfg80211_connect_params *)rtw_malloc(sizeof(*pwdev_priv->connect_req));
4107
if (pwdev_priv->connect_req)
4108
_rtw_memcpy(pwdev_priv->connect_req, sme, sizeof(*pwdev_priv->connect_req));
4109
else
4110
RTW_WARN(FUNC_NDEV_FMT" alloc connect_req fail\n", FUNC_NDEV_ARG(ndev));
4111
4112
_exit_critical_bh(&pwdev_priv->connect_req_lock, &irqL);
4113
4114
RTW_INFO("set ssid:dot11AuthAlgrthm=%d, dot11PrivacyAlgrthm=%d, dot118021XGrpPrivacy=%d\n", psecuritypriv->dot11AuthAlgrthm, psecuritypriv->dot11PrivacyAlgrthm,
4115
psecuritypriv->dot118021XGrpPrivacy);
4116
4117
cancel_ps_deny:
4118
rtw_ps_deny_cancel(padapter, PS_DENY_JOIN);
4119
4120
exit:
4121
RTW_INFO("<=%s, ret %d\n", __FUNCTION__, ret);
4122
4123
#if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_CONNECT)
4124
rtw_wdev_set_not_indic_disco(pwdev_priv, 0);
4125
#endif
4126
4127
return ret;
4128
}
4129
4130
static int cfg80211_rtw_disconnect(struct wiphy *wiphy, struct net_device *ndev,
4131
u16 reason_code)
4132
{
4133
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4134
4135
RTW_INFO(FUNC_NDEV_FMT" - Start to Disconnect\n", FUNC_NDEV_ARG(ndev));
4136
4137
#if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
4138
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
4139
if (!wiphy->dev.power.is_prepared)
4140
#endif
4141
rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 1);
4142
#endif
4143
4144
rtw_set_to_roam(padapter, 0);
4145
4146
/* if(check_fwstate(&padapter->mlmepriv, _FW_LINKED)) */
4147
{
4148
_rtw_disconnect(wiphy, ndev);
4149
}
4150
4151
#if (RTW_CFG80211_BLOCK_STA_DISCON_EVENT & RTW_CFG80211_BLOCK_DISCON_WHEN_DISCONNECT)
4152
rtw_wdev_set_not_indic_disco(adapter_wdev_data(padapter), 0);
4153
#endif
4154
4155
RTW_INFO(FUNC_NDEV_FMT" return 0\n", FUNC_NDEV_ARG(ndev));
4156
return 0;
4157
}
4158
4159
static int cfg80211_rtw_set_txpower(struct wiphy *wiphy,
4160
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4161
struct wireless_dev *wdev,
4162
#endif
4163
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) || defined(COMPAT_KERNEL_RELEASE)
4164
enum nl80211_tx_power_setting type, int mbm)
4165
#else
4166
enum tx_power_setting type, int dbm)
4167
#endif
4168
{
4169
4170
// Set TXPower code from aircrack-ng 5.6.4.2
4171
4172
_adapter *padapter = wiphy_to_adapter(wiphy);
4173
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4174
int value;
4175
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)) || defined(COMPAT_KERNEL_RELEASE)
4176
value = mbm/100;
4177
#else
4178
value = dbm;
4179
#endif
4180
4181
// Limits to '4000mw'
4182
if(value < 0)
4183
value = 0;
4184
if(value > 40)
4185
value = 40;
4186
4187
if(type == NL80211_TX_POWER_FIXED) {
4188
pHalData->CurrentTxPwrIdx = value;
4189
rtw_hal_set_tx_power_level(padapter, pHalData->current_channel);
4190
} else
4191
return -EOPNOTSUPP;
4192
4193
#if 0
4194
struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
4195
int ret;
4196
4197
switch (type) {
4198
case NL80211_TX_POWER_AUTOMATIC:
4199
return 0;
4200
case NL80211_TX_POWER_FIXED:
4201
if (mbm < 0 || (mbm % 100))
4202
return -EOPNOTSUPP;
4203
4204
if (!test_bit(IWM_STATUS_READY, &iwm->status))
4205
return 0;
4206
4207
ret = iwm_umac_set_config_fix(iwm, UMAC_PARAM_TBL_CFG_FIX,
4208
CFG_TX_PWR_LIMIT_USR,
4209
MBM_TO_DBM(mbm) * 2);
4210
if (ret < 0)
4211
return ret;
4212
4213
return iwm_tx_power_trigger(iwm);
4214
default:
4215
IWM_ERR(iwm, "Unsupported power type: %d\n", type);
4216
return -EOPNOTSUPP;
4217
}
4218
#endif
4219
RTW_INFO("%s\n", __func__);
4220
return 0;
4221
}
4222
4223
static int cfg80211_rtw_get_txpower(struct wiphy *wiphy,
4224
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
4225
struct wireless_dev *wdev,
4226
#endif
4227
int *dbm)
4228
{
4229
_adapter *padapter = wiphy_to_adapter(wiphy);
4230
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4231
4232
RTW_INFO("%s\n", __func__);
4233
4234
*dbm = pHalData->CurrentTxPwrIdx;
4235
4236
return 0;
4237
}
4238
4239
inline bool rtw_cfg80211_pwr_mgmt(_adapter *adapter)
4240
{
4241
struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(adapter);
4242
return rtw_wdev_priv->power_mgmt;
4243
}
4244
4245
static int cfg80211_rtw_set_power_mgmt(struct wiphy *wiphy,
4246
struct net_device *ndev,
4247
bool enabled, int timeout)
4248
{
4249
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4250
struct rtw_wdev_priv *rtw_wdev_priv = adapter_wdev_data(padapter);
4251
4252
RTW_INFO(FUNC_NDEV_FMT" enabled:%u, timeout:%d\n", FUNC_NDEV_ARG(ndev),
4253
enabled, timeout);
4254
4255
rtw_wdev_priv->power_mgmt = enabled;
4256
4257
#ifdef CONFIG_LPS
4258
if (!enabled)
4259
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE_CFG80211_PWRMGMT, 0);
4260
#endif
4261
4262
return 0;
4263
}
4264
4265
static void _rtw_set_pmksa(struct net_device *ndev,
4266
u8 *bssid, u8 *pmkid)
4267
{
4268
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4269
struct security_priv *psecuritypriv = &padapter->securitypriv;
4270
u8 index, blInserted = _FALSE;
4271
4272
/* overwrite PMKID */
4273
for (index = 0 ; index < NUM_PMKID_CACHE; index++) {
4274
if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, bssid, ETH_ALEN) == _TRUE) {
4275
/* BSSID is matched, the same AP => rewrite with new PMKID. */
4276
RTW_INFO("BSSID("MAC_FMT") exists in the PMKList.\n", MAC_ARG(bssid));
4277
4278
_rtw_memcpy(psecuritypriv->PMKIDList[index].PMKID, pmkid, WLAN_PMKID_LEN);
4279
psecuritypriv->PMKIDList[index].bUsed = _TRUE;
4280
psecuritypriv->PMKIDIndex = index + 1;
4281
blInserted = _TRUE;
4282
break;
4283
}
4284
}
4285
4286
if (!blInserted) {
4287
/* Find a new entry */
4288
RTW_INFO("Use the new entry index = %d for this PMKID.\n",
4289
psecuritypriv->PMKIDIndex);
4290
4291
_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].Bssid, bssid, ETH_ALEN);
4292
_rtw_memcpy(psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].PMKID, pmkid, WLAN_PMKID_LEN);
4293
4294
psecuritypriv->PMKIDList[psecuritypriv->PMKIDIndex].bUsed = _TRUE;
4295
psecuritypriv->PMKIDIndex++ ;
4296
if (psecuritypriv->PMKIDIndex == 16)
4297
psecuritypriv->PMKIDIndex = 0;
4298
}
4299
}
4300
4301
static int cfg80211_rtw_set_pmksa(struct wiphy *wiphy,
4302
struct net_device *ndev,
4303
struct cfg80211_pmksa *pmksa)
4304
{
4305
u8 index, blInserted = _FALSE;
4306
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4307
struct mlme_priv *mlme = &padapter->mlmepriv;
4308
struct security_priv *psecuritypriv = &padapter->securitypriv;
4309
u8 strZeroMacAddress[ETH_ALEN] = { 0x00 };
4310
bool sae_auth = rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE);
4311
4312
RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
4313
, MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
4314
4315
if (_rtw_memcmp((u8 *)pmksa->bssid, strZeroMacAddress, ETH_ALEN) == _TRUE)
4316
return -EINVAL;
4317
4318
if (check_fwstate(mlme, _FW_LINKED) == _FALSE && !sae_auth) {
4319
RTW_INFO(FUNC_NDEV_FMT" not set pmksa cause not in linked state\n", FUNC_NDEV_ARG(ndev));
4320
return -EINVAL;
4321
}
4322
4323
_rtw_set_pmksa(ndev, (u8 *)pmksa->bssid, (u8 *)pmksa->pmkid);
4324
4325
if (sae_auth &&
4326
(psecuritypriv->extauth_status == WLAN_STATUS_SUCCESS)) {
4327
RTW_PRINT("SAE: auth success, start assoc\n");
4328
start_clnt_assoc(padapter);
4329
}
4330
4331
return 0;
4332
}
4333
4334
static int cfg80211_rtw_del_pmksa(struct wiphy *wiphy,
4335
struct net_device *ndev,
4336
struct cfg80211_pmksa *pmksa)
4337
{
4338
u8 index, bMatched = _FALSE;
4339
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4340
struct security_priv *psecuritypriv = &padapter->securitypriv;
4341
4342
RTW_INFO(FUNC_NDEV_FMT" "MAC_FMT" "KEY_FMT"\n", FUNC_NDEV_ARG(ndev)
4343
, MAC_ARG(pmksa->bssid), KEY_ARG(pmksa->pmkid));
4344
4345
for (index = 0 ; index < NUM_PMKID_CACHE; index++) {
4346
if (_rtw_memcmp(psecuritypriv->PMKIDList[index].Bssid, (u8 *)pmksa->bssid, ETH_ALEN) == _TRUE) {
4347
/* BSSID is matched, the same AP => Remove this PMKID information and reset it. */
4348
_rtw_memset(psecuritypriv->PMKIDList[index].Bssid, 0x00, ETH_ALEN);
4349
_rtw_memset(psecuritypriv->PMKIDList[index].PMKID, 0x00, WLAN_PMKID_LEN);
4350
psecuritypriv->PMKIDList[index].bUsed = _FALSE;
4351
bMatched = _TRUE;
4352
RTW_INFO(FUNC_NDEV_FMT" clear id:%hhu\n", FUNC_NDEV_ARG(ndev), index);
4353
break;
4354
}
4355
}
4356
4357
if (_FALSE == bMatched) {
4358
RTW_INFO(FUNC_NDEV_FMT" do not have matched BSSID\n"
4359
, FUNC_NDEV_ARG(ndev));
4360
return -EINVAL;
4361
}
4362
4363
return 0;
4364
}
4365
4366
static int cfg80211_rtw_flush_pmksa(struct wiphy *wiphy,
4367
struct net_device *ndev)
4368
{
4369
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4370
struct security_priv *psecuritypriv = &padapter->securitypriv;
4371
4372
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4373
4374
_rtw_memset(&psecuritypriv->PMKIDList[0], 0x00, sizeof(RT_PMKID_LIST) * NUM_PMKID_CACHE);
4375
psecuritypriv->PMKIDIndex = 0;
4376
4377
return 0;
4378
}
4379
4380
#ifdef CONFIG_AP_MODE
4381
void rtw_cfg80211_indicate_sta_assoc(_adapter *padapter, u8 *pmgmt_frame, uint frame_len)
4382
{
4383
#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE)
4384
s32 freq;
4385
int channel;
4386
struct wireless_dev *pwdev = padapter->rtw_wdev;
4387
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4388
#endif
4389
struct net_device *ndev = padapter->pnetdev;
4390
4391
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
4392
4393
#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
4394
{
4395
struct station_info sinfo;
4396
u8 ie_offset;
4397
if (get_frame_sub_type(pmgmt_frame) == WIFI_ASSOCREQ)
4398
ie_offset = _ASOCREQ_IE_OFFSET_;
4399
else /* WIFI_REASSOCREQ */
4400
ie_offset = _REASOCREQ_IE_OFFSET_;
4401
4402
memset(&sinfo, 0, sizeof(sinfo));
4403
sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4404
sinfo.assoc_req_ies = pmgmt_frame + WLAN_HDR_A3_LEN + ie_offset;
4405
sinfo.assoc_req_ies_len = frame_len - WLAN_HDR_A3_LEN - ie_offset;
4406
cfg80211_new_sta(ndev, get_addr2_ptr(pmgmt_frame), &sinfo, GFP_ATOMIC);
4407
}
4408
#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
4409
channel = pmlmeext->cur_channel;
4410
freq = rtw_ch2freq(channel);
4411
4412
#ifdef COMPAT_KERNEL_RELEASE
4413
rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
4414
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
4415
rtw_cfg80211_rx_mgmt(pwdev, freq, 0, pmgmt_frame, frame_len, GFP_ATOMIC);
4416
#else /* COMPAT_KERNEL_RELEASE */
4417
{
4418
/* to avoid WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION) when calling cfg80211_send_rx_assoc() */
4419
#ifndef CONFIG_PLATFORM_MSTAR
4420
pwdev->iftype = NL80211_IFTYPE_STATION;
4421
#endif /* CONFIG_PLATFORM_MSTAR */
4422
RTW_INFO("iftype=%d before call cfg80211_send_rx_assoc()\n", pwdev->iftype);
4423
rtw_cfg80211_send_rx_assoc(padapter, NULL, pmgmt_frame, frame_len);
4424
RTW_INFO("iftype=%d after call cfg80211_send_rx_assoc()\n", pwdev->iftype);
4425
pwdev->iftype = NL80211_IFTYPE_AP;
4426
/* cfg80211_rx_action(padapter->pnetdev, freq, pmgmt_frame, frame_len, GFP_ATOMIC); */
4427
}
4428
#endif /* COMPAT_KERNEL_RELEASE */
4429
#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
4430
4431
}
4432
4433
void rtw_cfg80211_indicate_sta_disassoc(_adapter *padapter, const u8 *da, unsigned short reason)
4434
{
4435
#if !defined(RTW_USE_CFG80211_STA_EVENT) && !defined(COMPAT_KERNEL_RELEASE)
4436
s32 freq;
4437
int channel;
4438
u8 *pmgmt_frame;
4439
uint frame_len;
4440
struct rtw_ieee80211_hdr *pwlanhdr;
4441
unsigned short *fctrl;
4442
u8 mgmt_buf[128] = {0};
4443
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4444
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4445
struct wireless_dev *wdev = padapter->rtw_wdev;
4446
#endif
4447
struct net_device *ndev = padapter->pnetdev;
4448
4449
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
4450
4451
#if defined(RTW_USE_CFG80211_STA_EVENT) || defined(COMPAT_KERNEL_RELEASE)
4452
cfg80211_del_sta(ndev, da, GFP_ATOMIC);
4453
#else /* defined(RTW_USE_CFG80211_STA_EVENT) */
4454
channel = pmlmeext->cur_channel;
4455
freq = rtw_ch2freq(channel);
4456
4457
pmgmt_frame = mgmt_buf;
4458
pwlanhdr = (struct rtw_ieee80211_hdr *)pmgmt_frame;
4459
4460
fctrl = &(pwlanhdr->frame_ctl);
4461
*(fctrl) = 0;
4462
4463
_rtw_memcpy(pwlanhdr->addr1, adapter_mac_addr(padapter), ETH_ALEN);
4464
_rtw_memcpy(pwlanhdr->addr2, da, ETH_ALEN);
4465
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
4466
4467
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4468
pmlmeext->mgnt_seq++;
4469
set_frame_sub_type(pmgmt_frame, WIFI_DEAUTH);
4470
4471
pmgmt_frame += sizeof(struct rtw_ieee80211_hdr_3addr);
4472
frame_len = sizeof(struct rtw_ieee80211_hdr_3addr);
4473
4474
reason = cpu_to_le16(reason);
4475
pmgmt_frame = rtw_set_fixed_ie(pmgmt_frame, _RSON_CODE_ , (unsigned char *)&reason, &frame_len);
4476
4477
#ifdef COMPAT_KERNEL_RELEASE
4478
rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
4479
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && !defined(CONFIG_CFG80211_FORCE_COMPATIBLE_2_6_37_UNDER)
4480
rtw_cfg80211_rx_mgmt(wdev, freq, 0, mgmt_buf, frame_len, GFP_ATOMIC);
4481
#else /* COMPAT_KERNEL_RELEASE */
4482
cfg80211_send_disassoc(padapter->pnetdev, mgmt_buf, frame_len);
4483
/* cfg80211_rx_action(padapter->pnetdev, freq, mgmt_buf, frame_len, GFP_ATOMIC); */
4484
#endif /* COMPAT_KERNEL_RELEASE */
4485
#endif /* defined(RTW_USE_CFG80211_STA_EVENT) */
4486
}
4487
4488
static int rtw_cfg80211_monitor_if_open(struct net_device *ndev)
4489
{
4490
int ret = 0;
4491
4492
RTW_INFO("%s\n", __func__);
4493
4494
return ret;
4495
}
4496
4497
static int rtw_cfg80211_monitor_if_close(struct net_device *ndev)
4498
{
4499
int ret = 0;
4500
4501
RTW_INFO("%s\n", __func__);
4502
4503
return ret;
4504
}
4505
4506
static int rtw_cfg80211_monitor_if_xmit_entry(struct sk_buff *skb, struct net_device *ndev)
4507
{
4508
int ret = 0;
4509
int rtap_len;
4510
int qos_len = 0;
4511
int dot11_hdr_len = 24;
4512
int snap_len = 6;
4513
unsigned char *pdata;
4514
u16 frame_ctl;
4515
unsigned char src_mac_addr[ETH_ALEN];
4516
unsigned char dst_mac_addr[ETH_ALEN];
4517
struct rtw_ieee80211_hdr *dot11_hdr;
4518
struct ieee80211_radiotap_header *rtap_hdr;
4519
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
4520
#ifdef CONFIG_DFS_MASTER
4521
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
4522
#endif
4523
4524
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
4525
4526
rtw_mstat_update(MSTAT_TYPE_SKB, MSTAT_ALLOC_SUCCESS, skb->truesize);
4527
4528
if (IS_CH_WAITING(rfctl)) {
4529
#ifdef CONFIG_DFS_MASTER
4530
if (rtw_rfctl_overlap_radar_detect_ch(rfctl))
4531
goto fail;
4532
#endif
4533
}
4534
4535
if (unlikely(skb->len < sizeof(struct ieee80211_radiotap_header)))
4536
goto fail;
4537
4538
rtap_hdr = (struct ieee80211_radiotap_header *)skb->data;
4539
if (unlikely(rtap_hdr->it_version))
4540
goto fail;
4541
4542
rtap_len = ieee80211_get_radiotap_len(skb->data);
4543
if (unlikely(skb->len < rtap_len))
4544
goto fail;
4545
4546
if (rtap_len != 14) {
4547
RTW_INFO("radiotap len (should be 14): %d\n", rtap_len);
4548
goto fail;
4549
}
4550
4551
/* Skip the ratio tap header */
4552
skb_pull(skb, rtap_len);
4553
4554
dot11_hdr = (struct rtw_ieee80211_hdr *)skb->data;
4555
frame_ctl = le16_to_cpu(dot11_hdr->frame_ctl);
4556
/* Check if the QoS bit is set */
4557
if ((frame_ctl & RTW_IEEE80211_FCTL_FTYPE) == RTW_IEEE80211_FTYPE_DATA) {
4558
/* Check if this ia a Wireless Distribution System (WDS) frame
4559
* which has 4 MAC addresses
4560
*/
4561
if (dot11_hdr->frame_ctl & 0x0080)
4562
qos_len = 2;
4563
if ((dot11_hdr->frame_ctl & 0x0300) == 0x0300)
4564
dot11_hdr_len += 6;
4565
4566
memcpy(dst_mac_addr, dot11_hdr->addr1, sizeof(dst_mac_addr));
4567
memcpy(src_mac_addr, dot11_hdr->addr2, sizeof(src_mac_addr));
4568
4569
/* Skip the 802.11 header, QoS (if any) and SNAP, but leave spaces for
4570
* for two MAC addresses
4571
*/
4572
skb_pull(skb, dot11_hdr_len + qos_len + snap_len - sizeof(src_mac_addr) * 2);
4573
pdata = (unsigned char *)skb->data;
4574
memcpy(pdata, dst_mac_addr, sizeof(dst_mac_addr));
4575
memcpy(pdata + sizeof(dst_mac_addr), src_mac_addr, sizeof(src_mac_addr));
4576
4577
RTW_INFO("should be eapol packet\n");
4578
4579
/* Use the real net device to transmit the packet */
4580
ret = _rtw_xmit_entry(skb, padapter->pnetdev);
4581
4582
return ret;
4583
4584
} else if ((frame_ctl & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE))
4585
== (RTW_IEEE80211_FTYPE_MGMT | RTW_IEEE80211_STYPE_ACTION)
4586
) {
4587
/* only for action frames */
4588
struct xmit_frame *pmgntframe;
4589
struct pkt_attrib *pattrib;
4590
unsigned char *pframe;
4591
/* u8 category, action, OUI_Subtype, dialogToken=0; */
4592
/* unsigned char *frame_body; */
4593
struct rtw_ieee80211_hdr *pwlanhdr;
4594
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4595
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4596
u8 *buf = skb->data;
4597
u32 len = skb->len;
4598
u8 category, action;
4599
int type = -1;
4600
4601
if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
4602
RTW_INFO(FUNC_NDEV_FMT" frame_control:0x%x\n", FUNC_NDEV_ARG(ndev),
4603
le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
4604
goto fail;
4605
}
4606
4607
RTW_INFO("RTW_Tx:da="MAC_FMT" via "FUNC_NDEV_FMT"\n",
4608
MAC_ARG(GetAddr1Ptr(buf)), FUNC_NDEV_ARG(ndev));
4609
#ifdef CONFIG_P2P
4610
type = rtw_p2p_check_frames(padapter, buf, len, _TRUE);
4611
if (type >= 0)
4612
goto dump;
4613
#endif
4614
if (category == RTW_WLAN_CATEGORY_PUBLIC)
4615
RTW_INFO("RTW_Tx:%s\n", action_public_str(action));
4616
else
4617
RTW_INFO("RTW_Tx:category(%u), action(%u)\n", category, action);
4618
#ifdef CONFIG_P2P
4619
dump:
4620
#endif
4621
/* starting alloc mgmt frame to dump it */
4622
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4623
if (pmgntframe == NULL)
4624
goto fail;
4625
4626
/* update attribute */
4627
pattrib = &pmgntframe->attrib;
4628
update_mgntframe_attrib(padapter, pattrib);
4629
pattrib->retry_ctrl = _FALSE;
4630
4631
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4632
4633
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4634
4635
_rtw_memcpy(pframe, (void *)buf, len);
4636
pattrib->pktlen = len;
4637
4638
#ifdef CONFIG_P2P
4639
if (type >= 0)
4640
rtw_xframe_chk_wfd_ie(pmgntframe);
4641
#endif /* CONFIG_P2P */
4642
4643
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4644
/* update seq number */
4645
pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
4646
pattrib->seqnum = pmlmeext->mgnt_seq;
4647
pmlmeext->mgnt_seq++;
4648
4649
4650
pattrib->last_txcmdsz = pattrib->pktlen;
4651
4652
dump_mgntframe(padapter, pmgntframe);
4653
4654
} else
4655
RTW_INFO("frame_ctl=0x%x\n", frame_ctl & (RTW_IEEE80211_FCTL_FTYPE | RTW_IEEE80211_FCTL_STYPE));
4656
4657
4658
fail:
4659
4660
rtw_skb_free(skb);
4661
4662
return 0;
4663
4664
}
4665
4666
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
4667
static void rtw_cfg80211_monitor_if_set_multicast_list(struct net_device *ndev)
4668
{
4669
RTW_INFO("%s\n", __func__);
4670
}
4671
#endif
4672
static int rtw_cfg80211_monitor_if_set_mac_address(struct net_device *ndev, void *addr)
4673
{
4674
int ret = 0;
4675
4676
RTW_INFO("%s\n", __func__);
4677
4678
return ret;
4679
}
4680
4681
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
4682
static const struct net_device_ops rtw_cfg80211_monitor_if_ops = {
4683
.ndo_open = rtw_cfg80211_monitor_if_open,
4684
.ndo_stop = rtw_cfg80211_monitor_if_close,
4685
.ndo_start_xmit = rtw_cfg80211_monitor_if_xmit_entry,
4686
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
4687
.ndo_set_multicast_list = rtw_cfg80211_monitor_if_set_multicast_list,
4688
#endif
4689
.ndo_set_mac_address = rtw_cfg80211_monitor_if_set_mac_address,
4690
};
4691
#endif
4692
4693
static int rtw_cfg80211_add_monitor_if(_adapter *padapter, char *name, struct net_device **ndev)
4694
{
4695
int ret = 0;
4696
struct net_device *mon_ndev = NULL;
4697
struct wireless_dev *mon_wdev = NULL;
4698
struct rtw_netdev_priv_indicator *pnpi;
4699
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
4700
4701
if (!name) {
4702
RTW_INFO(FUNC_ADPT_FMT" without specific name\n", FUNC_ADPT_ARG(padapter));
4703
ret = -EINVAL;
4704
goto out;
4705
}
4706
4707
if (pwdev_priv->pmon_ndev) {
4708
RTW_INFO(FUNC_ADPT_FMT" monitor interface exist: "NDEV_FMT"\n",
4709
FUNC_ADPT_ARG(padapter), NDEV_ARG(pwdev_priv->pmon_ndev));
4710
ret = -EBUSY;
4711
goto out;
4712
}
4713
4714
mon_ndev = alloc_etherdev(sizeof(struct rtw_netdev_priv_indicator));
4715
if (!mon_ndev) {
4716
RTW_INFO(FUNC_ADPT_FMT" allocate ndev fail\n", FUNC_ADPT_ARG(padapter));
4717
ret = -ENOMEM;
4718
goto out;
4719
}
4720
4721
mon_ndev->type = ARPHRD_IEEE80211_RADIOTAP;
4722
strncpy(mon_ndev->name, name, IFNAMSIZ);
4723
mon_ndev->name[IFNAMSIZ - 1] = 0;
4724
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4, 11, 8))
4725
mon_ndev->priv_destructor = rtw_ndev_destructor;
4726
#else
4727
mon_ndev->destructor = rtw_ndev_destructor;
4728
#endif
4729
4730
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
4731
mon_ndev->netdev_ops = &rtw_cfg80211_monitor_if_ops;
4732
#else
4733
mon_ndev->open = rtw_cfg80211_monitor_if_open;
4734
mon_ndev->stop = rtw_cfg80211_monitor_if_close;
4735
mon_ndev->hard_start_xmit = rtw_cfg80211_monitor_if_xmit_entry;
4736
mon_ndev->set_mac_address = rtw_cfg80211_monitor_if_set_mac_address;
4737
#endif
4738
4739
pnpi = netdev_priv(mon_ndev);
4740
pnpi->priv = padapter;
4741
pnpi->sizeof_priv = sizeof(_adapter);
4742
4743
/* wdev */
4744
mon_wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
4745
if (!mon_wdev) {
4746
RTW_INFO(FUNC_ADPT_FMT" allocate mon_wdev fail\n", FUNC_ADPT_ARG(padapter));
4747
ret = -ENOMEM;
4748
goto out;
4749
}
4750
4751
mon_wdev->wiphy = padapter->rtw_wdev->wiphy;
4752
mon_wdev->netdev = mon_ndev;
4753
mon_wdev->iftype = NL80211_IFTYPE_MONITOR;
4754
mon_ndev->ieee80211_ptr = mon_wdev;
4755
4756
ret = register_netdevice(mon_ndev);
4757
if (ret)
4758
goto out;
4759
4760
*ndev = pwdev_priv->pmon_ndev = mon_ndev;
4761
_rtw_memcpy(pwdev_priv->ifname_mon, name, IFNAMSIZ + 1);
4762
4763
out:
4764
if (ret && mon_wdev) {
4765
rtw_mfree((u8 *)mon_wdev, sizeof(struct wireless_dev));
4766
mon_wdev = NULL;
4767
}
4768
4769
if (ret && mon_ndev) {
4770
free_netdev(mon_ndev);
4771
*ndev = mon_ndev = NULL;
4772
}
4773
4774
return ret;
4775
}
4776
4777
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4778
static struct wireless_dev *
4779
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
4780
static struct net_device *
4781
#else
4782
static int
4783
#endif
4784
cfg80211_rtw_add_virtual_intf(
4785
struct wiphy *wiphy,
4786
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 7, 0))
4787
const char *name,
4788
#else
4789
char *name,
4790
#endif
4791
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
4792
unsigned char name_assign_type,
4793
#endif
4794
enum nl80211_iftype type,
4795
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
4796
u32 *flags,
4797
#endif
4798
struct vif_params *params)
4799
{
4800
int ret = 0;
4801
struct wireless_dev *wdev = NULL;
4802
struct net_device *ndev = NULL;
4803
_adapter *padapter;
4804
struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
4805
4806
rtw_set_rtnl_lock_holder(dvobj, current);
4807
4808
RTW_INFO(FUNC_WIPHY_FMT" name:%s, type:%d\n", FUNC_WIPHY_ARG(wiphy), name, type);
4809
4810
switch (type) {
4811
case NL80211_IFTYPE_MONITOR:
4812
padapter = wiphy_to_adapter(wiphy); /* TODO: get ap iface ? */
4813
ret = rtw_cfg80211_add_monitor_if(padapter, (char *)name, &ndev);
4814
if (ret == 0)
4815
wdev = ndev->ieee80211_ptr;
4816
break;
4817
4818
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
4819
case NL80211_IFTYPE_P2P_CLIENT:
4820
case NL80211_IFTYPE_P2P_GO:
4821
#endif
4822
case NL80211_IFTYPE_STATION:
4823
case NL80211_IFTYPE_AP:
4824
#ifdef CONFIG_RTW_MESH
4825
case NL80211_IFTYPE_MESH_POINT:
4826
#endif
4827
padapter = dvobj_get_unregisterd_adapter(dvobj);
4828
if (!padapter) {
4829
RTW_WARN("adapter pool empty!\n");
4830
ret = -ENODEV;
4831
break;
4832
}
4833
if (rtw_os_ndev_init(padapter, name) != _SUCCESS) {
4834
RTW_WARN("ndev init fail!\n");
4835
ret = -ENODEV;
4836
break;
4837
}
4838
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
4839
if (type == NL80211_IFTYPE_P2P_CLIENT || type == NL80211_IFTYPE_P2P_GO)
4840
rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
4841
#endif
4842
ndev = padapter->pnetdev;
4843
wdev = ndev->ieee80211_ptr;
4844
break;
4845
4846
#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
4847
case NL80211_IFTYPE_P2P_DEVICE:
4848
ret = rtw_pd_iface_alloc(wiphy, name, &wdev);
4849
break;
4850
#endif
4851
4852
case NL80211_IFTYPE_ADHOC:
4853
case NL80211_IFTYPE_AP_VLAN:
4854
case NL80211_IFTYPE_WDS:
4855
default:
4856
ret = -ENODEV;
4857
RTW_INFO("Unsupported interface type\n");
4858
break;
4859
}
4860
4861
if (ndev)
4862
RTW_INFO(FUNC_WIPHY_FMT" ndev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), ndev, ret);
4863
else
4864
RTW_INFO(FUNC_WIPHY_FMT" wdev:%p, ret:%d\n", FUNC_WIPHY_ARG(wiphy), wdev, ret);
4865
4866
rtw_set_rtnl_lock_holder(dvobj, NULL);
4867
4868
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4869
return wdev ? wdev : ERR_PTR(ret);
4870
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
4871
return ndev ? ndev : ERR_PTR(ret);
4872
#else
4873
return ret;
4874
#endif
4875
}
4876
4877
static int cfg80211_rtw_del_virtual_intf(struct wiphy *wiphy,
4878
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4879
struct wireless_dev *wdev
4880
#else
4881
struct net_device *ndev
4882
#endif
4883
)
4884
{
4885
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
4886
struct net_device *ndev = wdev_to_ndev(wdev);
4887
#endif
4888
int ret = 0;
4889
struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
4890
_adapter *adapter;
4891
struct rtw_wdev_priv *pwdev_priv;
4892
4893
rtw_set_rtnl_lock_holder(dvobj, current);
4894
4895
if (ndev) {
4896
adapter = (_adapter *)rtw_netdev_priv(ndev);
4897
pwdev_priv = adapter_wdev_data(adapter);
4898
4899
if (ndev == pwdev_priv->pmon_ndev) {
4900
unregister_netdevice(ndev);
4901
pwdev_priv->pmon_ndev = NULL;
4902
pwdev_priv->ifname_mon[0] = '\0';
4903
RTW_INFO(FUNC_NDEV_FMT" remove monitor ndev\n", FUNC_NDEV_ARG(ndev));
4904
} else {
4905
RTW_INFO(FUNC_NDEV_FMT" unregister ndev\n", FUNC_NDEV_ARG(ndev));
4906
rtw_os_ndev_unregister(adapter);
4907
}
4908
} else
4909
#if defined(CONFIG_P2P) && defined(RTW_DEDICATED_P2P_DEVICE)
4910
if (wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) {
4911
if (wdev == wiphy_to_pd_wdev(wiphy))
4912
rtw_pd_iface_free(wiphy);
4913
else {
4914
RTW_ERR(FUNC_WIPHY_FMT" unknown P2P Device wdev:%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
4915
rtw_warn_on(1);
4916
}
4917
} else
4918
#endif
4919
{
4920
ret = -EINVAL;
4921
goto exit;
4922
}
4923
4924
exit:
4925
rtw_set_rtnl_lock_holder(dvobj, NULL);
4926
return ret;
4927
}
4928
4929
static int rtw_add_beacon(_adapter *adapter, const u8 *head, size_t head_len, const u8 *tail, size_t tail_len)
4930
{
4931
int ret = 0;
4932
u8 *pbuf = NULL;
4933
uint len, wps_ielen = 0;
4934
uint p2p_ielen = 0;
4935
u8 got_p2p_ie = _FALSE;
4936
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
4937
/* struct sta_priv *pstapriv = &padapter->stapriv; */
4938
4939
4940
RTW_INFO("%s beacon_head_len=%zu, beacon_tail_len=%zu\n", __FUNCTION__, head_len, tail_len);
4941
4942
4943
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
4944
return -EINVAL;
4945
4946
if (head_len < 24)
4947
return -EINVAL;
4948
4949
#ifdef CONFIG_FW_HANDLE_TXBCN
4950
if (!rtw_ap_nums_check(adapter)) {
4951
RTW_ERR(FUNC_ADPT_FMT"failed, con't support over %d BCN\n", FUNC_ADPT_ARG(adapter), CONFIG_LIMITED_AP_NUM);
4952
return -EINVAL;
4953
}
4954
#endif /*CONFIG_FW_HANDLE_TXBCN*/
4955
4956
pbuf = rtw_zmalloc(head_len + tail_len);
4957
if (!pbuf)
4958
return -ENOMEM;
4959
4960
4961
/* _rtw_memcpy(&pstapriv->max_num_sta, param->u.bcn_ie.reserved, 2); */
4962
4963
/* if((pstapriv->max_num_sta>NUM_STA) || (pstapriv->max_num_sta<=0)) */
4964
/* pstapriv->max_num_sta = NUM_STA; */
4965
4966
4967
_rtw_memcpy(pbuf, (void *)head + 24, head_len - 24); /* 24=beacon header len. */
4968
_rtw_memcpy(pbuf + head_len - 24, (void *)tail, tail_len);
4969
4970
len = head_len + tail_len - 24;
4971
4972
/* check wps ie if inclued */
4973
if (rtw_get_wps_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &wps_ielen))
4974
RTW_INFO("add bcn, wps_ielen=%d\n", wps_ielen);
4975
4976
#ifdef CONFIG_P2P
4977
if (adapter->wdinfo.driver_interface == DRIVER_CFG80211) {
4978
/* check p2p if enable */
4979
if (rtw_get_p2p_ie(pbuf + _FIXED_IE_LENGTH_, len - _FIXED_IE_LENGTH_, NULL, &p2p_ielen)) {
4980
struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
4981
4982
RTW_INFO("got p2p_ie, len=%d\n", p2p_ielen);
4983
4984
got_p2p_ie = _TRUE;
4985
4986
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) {
4987
RTW_INFO("Enable P2P function for the first time\n");
4988
rtw_p2p_enable(adapter, P2P_ROLE_GO);
4989
4990
adapter->stapriv.expire_to = 3; /* 3x2 = 6 sec in p2p mode */
4991
} else {
4992
RTW_INFO("enter GO Mode, p2p_ielen=%d\n", p2p_ielen);
4993
4994
rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
4995
rtw_p2p_set_state(pwdinfo, P2P_STATE_GONEGO_OK);
4996
pwdinfo->intent = 15;
4997
}
4998
}
4999
}
5000
#endif /* CONFIG_P2P */
5001
5002
/* pbss_network->IEs will not include p2p_ie, wfd ie */
5003
rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, P2P_OUI, 4);
5004
rtw_ies_remove_ie(pbuf, &len, _BEACON_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, WFD_OUI, 4);
5005
5006
if (rtw_check_beacon_data(adapter, pbuf, len) == _SUCCESS) {
5007
#ifdef CONFIG_P2P
5008
/* check p2p if enable */
5009
if (got_p2p_ie == _TRUE) {
5010
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
5011
struct wifidirect_info *pwdinfo = &(adapter->wdinfo);
5012
pwdinfo->operating_channel = pmlmeext->cur_channel;
5013
}
5014
#endif /* CONFIG_P2P */
5015
ret = 0;
5016
} else
5017
ret = -EINVAL;
5018
5019
5020
rtw_mfree(pbuf, head_len + tail_len);
5021
5022
return ret;
5023
}
5024
5025
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
5026
static int cfg80211_rtw_add_beacon(struct wiphy *wiphy, struct net_device *ndev,
5027
struct beacon_parameters *info)
5028
{
5029
int ret = 0;
5030
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5031
5032
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5033
5034
if (rtw_cfg80211_sync_iftype(adapter) != _SUCCESS) {
5035
ret = -ENOTSUPP;
5036
goto exit;
5037
}
5038
rtw_mi_scan_abort(adapter, _TRUE);
5039
rtw_mi_buddy_set_scan_deny(adapter, 300);
5040
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
5041
ret = rtw_add_beacon(adapter, info->beacon.head, info->beacon.head_len, info->beacon.tail, info->beacon.tail_len);
5042
#else
5043
ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
5044
#endif
5045
5046
exit:
5047
return ret;
5048
}
5049
5050
static int cfg80211_rtw_set_beacon(struct wiphy *wiphy, struct net_device *ndev,
5051
struct beacon_parameters *info)
5052
{
5053
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5054
struct mlme_ext_priv *pmlmeext = &(adapter->mlmeextpriv);
5055
5056
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5057
5058
pmlmeext->bstart_bss = _TRUE;
5059
5060
cfg80211_rtw_add_beacon(wiphy, ndev, info);
5061
5062
return 0;
5063
}
5064
5065
static int cfg80211_rtw_del_beacon(struct wiphy *wiphy, struct net_device *ndev)
5066
{
5067
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5068
5069
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5070
5071
rtw_stop_ap_cmd(adapter, RTW_CMDF_WAIT_ACK);
5072
return 0;
5073
}
5074
#else
5075
static int cfg80211_rtw_start_ap(struct wiphy *wiphy, struct net_device *ndev,
5076
struct cfg80211_ap_settings *settings)
5077
{
5078
int ret = 0;
5079
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5080
5081
RTW_INFO(FUNC_NDEV_FMT" hidden_ssid:%d, auth_type:%d\n", FUNC_NDEV_ARG(ndev),
5082
settings->hidden_ssid, settings->auth_type);
5083
5084
if (rtw_cfg80211_sync_iftype(adapter) != _SUCCESS) {
5085
ret = -ENOTSUPP;
5086
goto exit;
5087
}
5088
5089
/*
5090
Kernel < v5.1, the auth_type set as NL80211_AUTHTYPE_AUTOMATIC.
5091
if the AKM SAE in the RSN IE, we have to update the auth_type for SAE
5092
in rtw_check_beacon_data().
5093
*/
5094
rtw_cfg80211_set_auth_type(&adapter->securitypriv, settings->auth_type);
5095
5096
rtw_mi_scan_abort(adapter, _TRUE);
5097
rtw_mi_buddy_set_scan_deny(adapter, 300);
5098
5099
adapter->mlmeextpriv.mlmext_info.hidden_ssid_mode = settings->hidden_ssid;
5100
ret = rtw_add_beacon(adapter, settings->beacon.head, settings->beacon.head_len,
5101
settings->beacon.tail, settings->beacon.tail_len);
5102
5103
// In cases like WPS, the proberesp and assocresp IEs vary from the beacon, and need to be explicitly set
5104
if(ret == 0) {
5105
if(settings->beacon.proberesp_ies && settings->beacon.proberesp_ies_len > 0) {
5106
rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)settings->beacon.proberesp_ies,
5107
settings->beacon.proberesp_ies_len, 0x2/*PROBE_RESP*/);
5108
}
5109
if(settings->beacon.assocresp_ies && settings->beacon.assocresp_ies_len < 0) {
5110
rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)settings->beacon.assocresp_ies,
5111
settings->beacon.assocresp_ies_len, 0x4/*ASSOC_RESP*/);
5112
}
5113
}
5114
5115
if (settings->ssid && settings->ssid_len) {
5116
WLAN_BSSID_EX *pbss_network = &adapter->mlmepriv.cur_network.network;
5117
WLAN_BSSID_EX *pbss_network_ext = &adapter->mlmeextpriv.mlmext_info.network;
5118
5119
if (0)
5120
RTW_INFO(FUNC_ADPT_FMT" ssid:(%s,%zu), from ie:(%s,%d)\n", FUNC_ADPT_ARG(adapter),
5121
settings->ssid, settings->ssid_len,
5122
pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength);
5123
5124
_rtw_memcpy(pbss_network->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
5125
pbss_network->Ssid.SsidLength = settings->ssid_len;
5126
_rtw_memcpy(pbss_network_ext->Ssid.Ssid, (void *)settings->ssid, settings->ssid_len);
5127
pbss_network_ext->Ssid.SsidLength = settings->ssid_len;
5128
5129
if (0)
5130
RTW_INFO(FUNC_ADPT_FMT" after ssid:(%s,%d), (%s,%d)\n", FUNC_ADPT_ARG(adapter),
5131
pbss_network->Ssid.Ssid, pbss_network->Ssid.SsidLength,
5132
pbss_network_ext->Ssid.Ssid, pbss_network_ext->Ssid.SsidLength);
5133
}
5134
5135
exit:
5136
return ret;
5137
}
5138
5139
static int cfg80211_rtw_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
5140
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0))
5141
struct cfg80211_ap_update *info)
5142
#else
5143
struct cfg80211_beacon_data *info)
5144
#endif
5145
{
5146
int ret = 0;
5147
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5148
5149
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5150
5151
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0))
5152
ret = rtw_add_beacon(adapter, info->beacon.head, info->beacon.head_len, info->beacon.tail, info->beacon.tail_len);
5153
#else
5154
ret = rtw_add_beacon(adapter, info->head, info->head_len, info->tail, info->tail_len);
5155
#endif
5156
5157
// In cases like WPS, the proberesp and assocresp IEs vary from the beacon, and need to be explicitly set
5158
if(ret == 0) {
5159
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
5160
if(info->beacon.proberesp_ies && info->beacon.proberesp_ies_len > 0) {
5161
rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)info->beacon.proberesp_ies, info->beacon.proberesp_ies_len, 0x2/*PROBE_RESP*/);
5162
#else
5163
if(info->proberesp_ies && info->proberesp_ies_len > 0) {
5164
rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)info->proberesp_ies, info->proberesp_ies_len, 0x2/*PROBE_RESP*/);
5165
#endif
5166
}
5167
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6, 7, 0)
5168
if(info->beacon.assocresp_ies && info->beacon.assocresp_ies_len > 0) {
5169
rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)info->beacon.assocresp_ies, info->beacon.assocresp_ies_len, 0x4/*ASSOC_RESP*/);
5170
#else
5171
if(info->assocresp_ies && info->assocresp_ies_len > 0) {
5172
rtw_cfg80211_set_mgnt_wpsp2pie(ndev, (char *)info->assocresp_ies, info->assocresp_ies_len, 0x4/*ASSOC_RESP*/);
5173
#endif
5174
}
5175
}
5176
5177
return ret;
5178
}
5179
5180
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2))
5181
static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
5182
unsigned int link_id)
5183
#else
5184
static int cfg80211_rtw_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
5185
#endif
5186
{
5187
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5188
5189
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5190
5191
rtw_stop_ap_cmd(adapter, RTW_CMDF_WAIT_ACK);
5192
return 0;
5193
}
5194
#endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) */
5195
5196
#if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
5197
static int cfg80211_rtw_set_mac_acl(struct wiphy *wiphy, struct net_device *ndev,
5198
const struct cfg80211_acl_data *params)
5199
{
5200
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5201
u8 acl_mode = RTW_ACL_MODE_DISABLED;
5202
int ret = -1;
5203
int i;
5204
5205
if (!params) {
5206
RTW_WARN(FUNC_ADPT_FMT" params NULL\n", FUNC_ADPT_ARG(adapter));
5207
rtw_macaddr_acl_clear(adapter, RTW_ACL_PERIOD_BSS);
5208
goto exit;
5209
}
5210
5211
RTW_INFO(FUNC_ADPT_FMT" acl_policy:%d, entry_num:%d\n"
5212
, FUNC_ADPT_ARG(adapter), params->acl_policy, params->n_acl_entries);
5213
5214
if (params->acl_policy == NL80211_ACL_POLICY_ACCEPT_UNLESS_LISTED)
5215
acl_mode = RTW_ACL_MODE_ACCEPT_UNLESS_LISTED;
5216
else if (params->acl_policy == NL80211_ACL_POLICY_DENY_UNLESS_LISTED)
5217
acl_mode = RTW_ACL_MODE_DENY_UNLESS_LISTED;
5218
5219
rtw_macaddr_acl_clear(adapter, RTW_ACL_PERIOD_BSS);
5220
5221
rtw_set_macaddr_acl(adapter, RTW_ACL_PERIOD_BSS, acl_mode);
5222
5223
for (i = 0; i < params->n_acl_entries; i++)
5224
rtw_acl_add_sta(adapter, RTW_ACL_PERIOD_BSS, params->mac_addrs[i].addr);
5225
5226
ret = 0;
5227
5228
exit:
5229
return ret;
5230
}
5231
#endif /* CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0)) */
5232
5233
const char *_nl80211_sta_flags_str[] = {
5234
"INVALID",
5235
"AUTHORIZED",
5236
"SHORT_PREAMBLE",
5237
"WME",
5238
"MFP",
5239
"AUTHENTICATED",
5240
"TDLS_PEER",
5241
"ASSOCIATED",
5242
};
5243
5244
#define nl80211_sta_flags_str(_f) ((_f <= NL80211_STA_FLAG_MAX) ? _nl80211_sta_flags_str[_f] : _nl80211_sta_flags_str[0])
5245
5246
const char *_nl80211_plink_state_str[] = {
5247
"LISTEN",
5248
"OPN_SNT",
5249
"OPN_RCVD",
5250
"CNF_RCVD",
5251
"ESTAB",
5252
"HOLDING",
5253
"BLOCKED",
5254
"UNKNOWN",
5255
};
5256
5257
#define nl80211_plink_state_str(_s) ((_s < NUM_NL80211_PLINK_STATES) ? _nl80211_plink_state_str[_s] : _nl80211_plink_state_str[NUM_NL80211_PLINK_STATES])
5258
5259
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 10, 0))
5260
#define NL80211_PLINK_ACTION_NO_ACTION PLINK_ACTION_INVALID
5261
#define NL80211_PLINK_ACTION_OPEN PLINK_ACTION_OPEN
5262
#define NL80211_PLINK_ACTION_BLOCK PLINK_ACTION_BLOCK
5263
#define NUM_NL80211_PLINK_ACTIONS 3
5264
#endif
5265
5266
const char *_nl80211_plink_actions_str[] = {
5267
"NO_ACTION",
5268
"OPEN",
5269
"BLOCK",
5270
"UNKNOWN",
5271
};
5272
5273
#define nl80211_plink_actions_str(_a) ((_a < NUM_NL80211_PLINK_ACTIONS) ? _nl80211_plink_actions_str[_a] : _nl80211_plink_actions_str[NUM_NL80211_PLINK_ACTIONS])
5274
5275
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
5276
const char *_nl80211_mesh_power_mode_str[] = {
5277
"UNKNOWN",
5278
"ACTIVE",
5279
"LIGHT_SLEEP",
5280
"DEEP_SLEEP",
5281
};
5282
5283
#define nl80211_mesh_power_mode_str(_p) ((_p <= NL80211_MESH_POWER_MAX) ? _nl80211_mesh_power_mode_str[_p] : _nl80211_mesh_power_mode_str[0])
5284
#endif
5285
5286
void dump_station_parameters(void *sel, struct wiphy *wiphy, const struct station_parameters *params)
5287
{
5288
#if DBG_RTW_CFG80211_STA_PARAM
5289
if (params->supported_rates_len) {
5290
#define SUPP_RATES_BUF_LEN (3 * RTW_G_RATES_NUM + 1)
5291
int i;
5292
char supp_rates_buf[SUPP_RATES_BUF_LEN] = {0};
5293
u8 cnt = 0;
5294
5295
rtw_warn_on(params->supported_rates_len > RTW_G_RATES_NUM);
5296
5297
for (i = 0; i < params->supported_rates_len; i++) {
5298
if (i >= RTW_G_RATES_NUM)
5299
break;
5300
cnt += snprintf(supp_rates_buf + cnt, SUPP_RATES_BUF_LEN - cnt -1
5301
, "%02X ", params->supported_rates[i]);
5302
if (cnt >= SUPP_RATES_BUF_LEN - 1)
5303
break;
5304
}
5305
5306
RTW_PRINT_SEL(sel, "supported_rates:%s\n", supp_rates_buf);
5307
}
5308
5309
if (params->vlan)
5310
RTW_PRINT_SEL(sel, "vlan:"NDEV_FMT"\n", NDEV_ARG(params->vlan));
5311
5312
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 31))
5313
if (params->sta_flags_mask) {
5314
#define STA_FLAGS_BUF_LEN 128
5315
int i = 0;
5316
char sta_flags_buf[STA_FLAGS_BUF_LEN] = {0};
5317
u8 cnt = 0;
5318
5319
for (i = 1; i <= NL80211_STA_FLAG_MAX; i++) {
5320
if (params->sta_flags_mask & BIT(i)) {
5321
cnt += snprintf(sta_flags_buf + cnt, STA_FLAGS_BUF_LEN - cnt -1, "%s=%u "
5322
, nl80211_sta_flags_str(i), (params->sta_flags_set & BIT(i)) ? 1 : 0);
5323
if (cnt >= STA_FLAGS_BUF_LEN - 1)
5324
break;
5325
}
5326
}
5327
5328
RTW_PRINT_SEL(sel, "sta_flags:%s\n", sta_flags_buf);
5329
}
5330
#else
5331
u32 station_flags;
5332
#error "TBD\n"
5333
#endif
5334
5335
if (params->listen_interval != -1)
5336
RTW_PRINT_SEL(sel, "listen_interval:%d\n", params->listen_interval);
5337
5338
if (params->aid)
5339
RTW_PRINT_SEL(sel, "aid:%u\n", params->aid);
5340
5341
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0))
5342
if (params->peer_aid)
5343
RTW_PRINT_SEL(sel, "peer_aid:%u\n", params->peer_aid);
5344
#endif
5345
5346
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26))
5347
if (params->plink_action != NL80211_PLINK_ACTION_NO_ACTION)
5348
RTW_PRINT_SEL(sel, "plink_action:%s\n", nl80211_plink_actions_str(params->plink_action));
5349
#endif
5350
5351
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
5352
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
5353
if (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5354
#endif
5355
RTW_PRINT_SEL(sel, "plink_state:%s\n"
5356
, nl80211_plink_state_str(params->plink_state));
5357
#endif
5358
5359
#if 0 /* TODO */
5360
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28))
5361
const struct ieee80211_ht_cap *ht_capa;
5362
#endif
5363
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
5364
const struct ieee80211_vht_cap *vht_capa;
5365
#endif
5366
#endif
5367
5368
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
5369
if (params->sta_modify_mask & STATION_PARAM_APPLY_UAPSD)
5370
RTW_PRINT_SEL(sel, "uapsd_queues:0x%02x\n", params->uapsd_queues);
5371
if (params->max_sp)
5372
RTW_PRINT_SEL(sel, "max_sp:%u\n", params->max_sp);
5373
#endif
5374
5375
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
5376
if (params->local_pm != NL80211_MESH_POWER_UNKNOWN) {
5377
RTW_PRINT_SEL(sel, "local_pm:%s\n"
5378
, nl80211_mesh_power_mode_str(params->local_pm));
5379
}
5380
5381
if (params->sta_modify_mask & STATION_PARAM_APPLY_CAPABILITY)
5382
RTW_PRINT_SEL(sel, "capability:0x%04x\n", params->capability);
5383
5384
#if 0 /* TODO */
5385
const u8 *ext_capab;
5386
u8 ext_capab_len;
5387
#endif
5388
#endif
5389
5390
#if 0 /* TODO */
5391
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0))
5392
const u8 *supported_channels;
5393
u8 supported_channels_len;
5394
const u8 *supported_oper_classes;
5395
u8 supported_oper_classes_len;
5396
#endif
5397
5398
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0))
5399
u8 opmode_notif;
5400
bool opmode_notif_used;
5401
#endif
5402
5403
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
5404
int support_p2p_ps;
5405
#endif
5406
#endif
5407
#endif /* DBG_RTW_CFG80211_STA_PARAM */
5408
}
5409
5410
static int cfg80211_rtw_add_station(struct wiphy *wiphy, struct net_device *ndev,
5411
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
5412
u8 *mac,
5413
#else
5414
const u8 *mac,
5415
#endif
5416
struct station_parameters *params)
5417
{
5418
int ret = 0;
5419
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
5420
#if defined(CONFIG_TDLS) || defined(CONFIG_RTW_MESH)
5421
struct sta_priv *pstapriv = &padapter->stapriv;
5422
#endif
5423
#ifdef CONFIG_TDLS
5424
struct sta_info *psta;
5425
#endif /* CONFIG_TDLS */
5426
5427
RTW_INFO(FUNC_NDEV_FMT" mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
5428
5429
#if CONFIG_RTW_MACADDR_ACL
5430
if (rtw_access_ctrl(padapter, mac) == _FALSE) {
5431
RTW_INFO(FUNC_NDEV_FMT" deny by macaddr ACL\n", FUNC_NDEV_ARG(ndev));
5432
ret = -EINVAL;
5433
goto exit;
5434
}
5435
#endif
5436
5437
dump_station_parameters(RTW_DBGDUMP, wiphy, params);
5438
5439
#ifdef CONFIG_RTW_MESH
5440
if (MLME_IS_MESH(padapter)) {
5441
struct rtw_mesh_cfg *mcfg = &padapter->mesh_cfg;
5442
struct rtw_mesh_info *minfo = &padapter->mesh_info;
5443
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
5444
struct mesh_plink_ent *plink = NULL;
5445
struct wlan_network *scanned = NULL;
5446
bool acnode = 0;
5447
u8 add_new_sta = 0, probe_req = 0;
5448
_irqL irqL;
5449
5450
if (params->plink_state != NL80211_PLINK_LISTEN) {
5451
RTW_WARN(FUNC_NDEV_FMT" %s\n", FUNC_NDEV_ARG(ndev), nl80211_plink_state_str(params->plink_state));
5452
rtw_warn_on(1);
5453
}
5454
if (!params->aid || params->aid > pstapriv->max_aid) {
5455
RTW_WARN(FUNC_NDEV_FMT" invalid aid:%u\n", FUNC_NDEV_ARG(ndev), params->aid);
5456
rtw_warn_on(1);
5457
ret = -EINVAL;
5458
goto exit;
5459
}
5460
5461
_enter_critical_bh(&(plink_ctl->lock), &irqL);
5462
5463
plink = _rtw_mesh_plink_get(padapter, mac);
5464
if (plink)
5465
goto release_plink_ctl;
5466
5467
#if CONFIG_RTW_MESH_PEER_BLACKLIST
5468
if (rtw_mesh_peer_blacklist_search(padapter, mac)) {
5469
RTW_INFO(FUNC_NDEV_FMT" deny by peer blacklist\n"
5470
, FUNC_NDEV_ARG(ndev));
5471
ret = -EINVAL;
5472
goto release_plink_ctl;
5473
}
5474
#endif
5475
5476
scanned = rtw_find_network(&padapter->mlmepriv.scanned_queue, mac);
5477
if (!scanned
5478
|| rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms
5479
) {
5480
if (!scanned)
5481
RTW_INFO(FUNC_NDEV_FMT" corresponding network not found\n", FUNC_NDEV_ARG(ndev));
5482
else
5483
RTW_INFO(FUNC_NDEV_FMT" corresponding network too old\n", FUNC_NDEV_ARG(ndev));
5484
5485
if (adapter_to_rfctl(padapter)->offch_state == OFFCHS_NONE)
5486
probe_req = 1;
5487
5488
ret = -EINVAL;
5489
goto release_plink_ctl;
5490
}
5491
5492
#if CONFIG_RTW_MESH_ACNODE_PREVENT
5493
if (plink_ctl->acnode_rsvd)
5494
acnode = rtw_mesh_scanned_is_acnode_confirmed(padapter, scanned);
5495
#endif
5496
5497
/* wpa_supplicant's auto peer will initiate peering when candidate peer is reported without max_peer_links consideration */
5498
if (plink_ctl->num >= mcfg->max_peer_links + acnode ? 1 : 0) {
5499
RTW_INFO(FUNC_NDEV_FMT" exceed max_peer_links:%u%s\n"
5500
, FUNC_NDEV_ARG(ndev), mcfg->max_peer_links, acnode ? " acn" : "");
5501
ret = -EINVAL;
5502
goto release_plink_ctl;
5503
}
5504
5505
if (!rtw_bss_is_candidate_mesh_peer(&padapter->mlmepriv.cur_network.network, &scanned->network, 1, 1)) {
5506
RTW_WARN(FUNC_NDEV_FMT" corresponding network is not candidate with same ch\n"
5507
, FUNC_NDEV_ARG(ndev));
5508
ret = -EINVAL;
5509
goto release_plink_ctl;
5510
}
5511
5512
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
5513
if (!rtw_mesh_cto_mgate_network_filter(padapter, scanned)) {
5514
RTW_INFO(FUNC_NDEV_FMT" peer filtered out by cto_mgate check\n"
5515
, FUNC_NDEV_ARG(ndev));
5516
ret = -EINVAL;
5517
goto release_plink_ctl;
5518
}
5519
#endif
5520
5521
if (_rtw_mesh_plink_add(padapter, mac) == _SUCCESS) {
5522
/* hook corresponding network in scan queue */
5523
plink = _rtw_mesh_plink_get(padapter, mac);
5524
plink->aid = params->aid;
5525
plink->scanned = scanned;
5526
5527
#if CONFIG_RTW_MESH_ACNODE_PREVENT
5528
if (acnode) {
5529
RTW_INFO(FUNC_ADPT_FMT" acnode "MAC_FMT"\n"
5530
, FUNC_ADPT_ARG(padapter), MAC_ARG(scanned->network.MacAddress));
5531
}
5532
#endif
5533
5534
add_new_sta = 1;
5535
} else {
5536
RTW_WARN(FUNC_NDEV_FMT" rtw_mesh_plink_add not success\n"
5537
, FUNC_NDEV_ARG(ndev));
5538
ret = -EINVAL;
5539
}
5540
release_plink_ctl:
5541
_exit_critical_bh(&(plink_ctl->lock), &irqL);
5542
5543
if (probe_req)
5544
issue_probereq(padapter, &padapter->mlmepriv.cur_network.network.mesh_id, mac);
5545
5546
if (add_new_sta) {
5547
struct station_info sinfo;
5548
5549
#ifdef CONFIG_DFS_MASTER
5550
if (IS_UNDER_CAC(adapter_to_rfctl(padapter)))
5551
rtw_force_stop_cac(adapter_to_rfctl(padapter), 300);
5552
#endif
5553
5554
/* indicate new sta */
5555
_rtw_memset(&sinfo, 0, sizeof(sinfo));
5556
cfg80211_new_sta(ndev, mac, &sinfo, GFP_ATOMIC);
5557
}
5558
goto exit;
5559
}
5560
#endif /* CONFIG_RTW_MESH */
5561
5562
#ifdef CONFIG_TDLS
5563
psta = rtw_get_stainfo(pstapriv, (u8 *)mac);
5564
if (psta == NULL) {
5565
psta = rtw_alloc_stainfo(pstapriv, (u8 *)mac);
5566
if (psta == NULL) {
5567
RTW_INFO("[%s] Alloc station for "MAC_FMT" fail\n", __FUNCTION__, MAC_ARG(mac));
5568
ret = -EOPNOTSUPP;
5569
goto exit;
5570
}
5571
}
5572
#endif /* CONFIG_TDLS */
5573
5574
exit:
5575
return ret;
5576
}
5577
5578
static int cfg80211_rtw_del_station(struct wiphy *wiphy, struct net_device *ndev,
5579
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
5580
u8 *mac
5581
#elif (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
5582
const u8 *mac
5583
#else
5584
struct station_del_parameters *params
5585
#endif
5586
)
5587
{
5588
int ret = 0;
5589
_irqL irqL;
5590
_list *phead, *plist;
5591
u8 updated = _FALSE;
5592
const u8 *target_mac;
5593
struct sta_info *psta = NULL;
5594
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
5595
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5596
struct sta_priv *pstapriv = &padapter->stapriv;
5597
5598
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 19, 0))
5599
target_mac = mac;
5600
#else
5601
target_mac = params->mac;
5602
#endif
5603
5604
RTW_INFO("+"FUNC_NDEV_FMT" mac=%pM\n", FUNC_NDEV_ARG(ndev), target_mac);
5605
5606
if (check_fwstate(pmlmepriv, (_FW_LINKED | WIFI_AP_STATE | WIFI_MESH_STATE)) != _TRUE) {
5607
RTW_INFO("%s, fw_state != FW_LINKED|WIFI_AP_STATE|WIFI_MESH_STATE\n", __func__);
5608
return -EINVAL;
5609
}
5610
5611
5612
if (!target_mac) {
5613
RTW_INFO("flush all sta, and cam_entry\n");
5614
5615
flush_all_cam_entry(padapter); /* clear CAM */
5616
5617
#ifdef CONFIG_AP_MODE
5618
ret = rtw_sta_flush(padapter, _TRUE);
5619
#endif
5620
return ret;
5621
}
5622
5623
5624
RTW_INFO("free sta macaddr =" MAC_FMT "\n", MAC_ARG(target_mac));
5625
5626
if (target_mac[0] == 0xff && target_mac[1] == 0xff &&
5627
target_mac[2] == 0xff && target_mac[3] == 0xff &&
5628
target_mac[4] == 0xff && target_mac[5] == 0xff)
5629
return -EINVAL;
5630
5631
5632
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
5633
5634
phead = &pstapriv->asoc_list;
5635
plist = get_next(phead);
5636
5637
/* check asoc_queue */
5638
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
5639
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
5640
5641
plist = get_next(plist);
5642
5643
if (_rtw_memcmp((u8 *)target_mac, psta->cmn.mac_addr, ETH_ALEN)) {
5644
if (psta->dot8021xalg == 1 && psta->bpairwise_key_installed == _FALSE)
5645
RTW_INFO("%s, sta's dot8021xalg = 1 and key_installed = _FALSE\n", __func__);
5646
else {
5647
RTW_INFO("free psta=%p, aid=%d\n", psta, psta->cmn.aid);
5648
5649
rtw_list_delete(&psta->asoc_list);
5650
pstapriv->asoc_list_cnt--;
5651
STA_SET_MESH_PLINK(psta, NULL);
5652
5653
/* _exit_critical_bh(&pstapriv->asoc_list_lock, &irqL); */
5654
if (MLME_IS_AP(padapter))
5655
updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_PREV_AUTH_NOT_VALID, _TRUE);
5656
else
5657
updated = ap_free_sta(padapter, psta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _TRUE);
5658
/* _enter_critical_bh(&pstapriv->asoc_list_lock, &irqL); */
5659
5660
psta = NULL;
5661
5662
break;
5663
}
5664
5665
}
5666
5667
}
5668
5669
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
5670
5671
associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
5672
5673
#ifdef CONFIG_RTW_MESH
5674
if (MLME_IS_MESH(padapter))
5675
rtw_mesh_plink_del(padapter, target_mac);
5676
#endif
5677
5678
RTW_INFO("-"FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5679
5680
return ret;
5681
5682
}
5683
5684
static int cfg80211_rtw_change_station(struct wiphy *wiphy, struct net_device *ndev,
5685
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 16, 0))
5686
u8 *mac,
5687
#else
5688
const u8 *mac,
5689
#endif
5690
struct station_parameters *params)
5691
{
5692
#ifdef CONFIG_RTW_MESH
5693
_adapter *adapter = (_adapter *)rtw_netdev_priv(ndev);
5694
struct sta_priv *stapriv = &adapter->stapriv;
5695
struct sta_info *sta = NULL;
5696
_irqL irqL;
5697
#endif
5698
int ret = 0;
5699
5700
RTW_INFO(FUNC_NDEV_FMT" mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(mac));
5701
5702
dump_station_parameters(RTW_DBGDUMP, wiphy, params);
5703
5704
#ifdef CONFIG_RTW_MESH
5705
if (MLME_IS_MESH(adapter)) {
5706
enum cfg80211_station_type sta_type = CFG80211_STA_MESH_PEER_USER;
5707
struct rtw_mesh_info *minfo = &adapter->mesh_info;
5708
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
5709
struct mesh_plink_ent *plink = NULL;
5710
_irqL irqL2;
5711
struct sta_info *del_sta = NULL;
5712
5713
ret = cfg80211_check_station_change(wiphy, params, sta_type);
5714
if (ret) {
5715
RTW_INFO("cfg80211_check_station_change return %d\n", ret);
5716
goto exit;
5717
}
5718
5719
_enter_critical_bh(&(plink_ctl->lock), &irqL2);
5720
5721
plink = _rtw_mesh_plink_get(adapter, mac);
5722
if (!plink) {
5723
ret = -ENOENT;
5724
goto release_plink_ctl;
5725
}
5726
5727
plink->plink_state = nl80211_plink_state_to_rtw_plink_state(params->plink_state);
5728
5729
#if CONFIG_RTW_MESH_ACNODE_PREVENT
5730
if (params->plink_state == NL80211_PLINK_OPN_SNT
5731
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
5732
&& (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5733
#endif
5734
) {
5735
if (rtw_mesh_scanned_is_acnode_confirmed(adapter, plink->scanned)
5736
&& rtw_mesh_acnode_prevent_allow_sacrifice(adapter)
5737
) {
5738
struct sta_info *sac = rtw_mesh_acnode_prevent_pick_sacrifice(adapter);
5739
5740
if (sac) {
5741
del_sta = sac;
5742
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
5743
if (!rtw_is_list_empty(&del_sta->asoc_list)) {
5744
rtw_list_delete(&del_sta->asoc_list);
5745
stapriv->asoc_list_cnt--;
5746
STA_SET_MESH_PLINK(del_sta, NULL);
5747
}
5748
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
5749
RTW_INFO(FUNC_ADPT_FMT" sacrifice "MAC_FMT" for acnode\n"
5750
, FUNC_ADPT_ARG(adapter), MAC_ARG(del_sta->cmn.mac_addr));
5751
}
5752
}
5753
} else
5754
#endif
5755
if ((params->plink_state == NL80211_PLINK_OPN_RCVD
5756
|| params->plink_state == NL80211_PLINK_CNF_RCVD
5757
|| params->plink_state == NL80211_PLINK_ESTAB)
5758
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
5759
&& (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5760
#endif
5761
) {
5762
sta = rtw_get_stainfo(stapriv, mac);
5763
if (!sta) {
5764
sta = rtw_alloc_stainfo(stapriv, mac);
5765
if (!sta)
5766
goto release_plink_ctl;
5767
}
5768
5769
if (params->plink_state == NL80211_PLINK_ESTAB) {
5770
if (rtw_mesh_peer_establish(adapter, plink, sta) != _SUCCESS) {
5771
rtw_free_stainfo(adapter, sta);
5772
ret = -ENOENT;
5773
goto release_plink_ctl;
5774
}
5775
}
5776
}
5777
else if (params->plink_state == NL80211_PLINK_HOLDING
5778
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
5779
&& (params->sta_modify_mask & STATION_PARAM_APPLY_PLINK_STATE)
5780
#endif
5781
) {
5782
del_sta = rtw_get_stainfo(stapriv, mac);
5783
if (!del_sta)
5784
goto release_plink_ctl;
5785
5786
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
5787
if (!rtw_is_list_empty(&del_sta->asoc_list)) {
5788
rtw_list_delete(&del_sta->asoc_list);
5789
stapriv->asoc_list_cnt--;
5790
STA_SET_MESH_PLINK(del_sta, NULL);
5791
}
5792
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
5793
}
5794
5795
release_plink_ctl:
5796
_exit_critical_bh(&(plink_ctl->lock), &irqL2);
5797
5798
if (del_sta) {
5799
u8 sta_addr[ETH_ALEN];
5800
u8 updated = _FALSE;
5801
5802
_rtw_memcpy(sta_addr, del_sta->cmn.mac_addr, ETH_ALEN);
5803
updated = ap_free_sta(adapter, del_sta, 0, 0, 1);
5804
rtw_mesh_expire_peer(stapriv->padapter, sta_addr);
5805
5806
associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
5807
}
5808
}
5809
5810
exit:
5811
#endif /* CONFIG_RTW_MESH */
5812
5813
return ret;
5814
}
5815
5816
struct sta_info *rtw_sta_info_get_by_idx(struct sta_priv *pstapriv, const int idx, u8 *asoc_list_num)
5817
{
5818
_list *phead, *plist;
5819
struct sta_info *psta = NULL;
5820
int i = 0;
5821
5822
phead = &pstapriv->asoc_list;
5823
plist = get_next(phead);
5824
5825
/* check asoc_queue */
5826
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
5827
if (idx == i)
5828
psta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
5829
plist = get_next(plist);
5830
i++;
5831
}
5832
5833
if (asoc_list_num)
5834
*asoc_list_num = i;
5835
5836
return psta;
5837
}
5838
5839
static int cfg80211_rtw_dump_station(struct wiphy *wiphy, struct net_device *ndev,
5840
int idx, u8 *mac, struct station_info *sinfo)
5841
{
5842
#define DBG_DUMP_STATION 0
5843
5844
int ret = 0;
5845
_irqL irqL;
5846
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
5847
struct sta_priv *pstapriv = &padapter->stapriv;
5848
struct sta_info *psta = NULL;
5849
#ifdef CONFIG_RTW_MESH
5850
struct mesh_plink_ent *plink = NULL;
5851
#endif
5852
u8 asoc_list_num;
5853
5854
if (DBG_DUMP_STATION)
5855
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5856
5857
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
5858
psta = rtw_sta_info_get_by_idx(pstapriv, idx, &asoc_list_num);
5859
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
5860
5861
#ifdef CONFIG_RTW_MESH
5862
if (MLME_IS_MESH(padapter)) {
5863
if (psta)
5864
plink = psta->plink;
5865
if (!plink)
5866
plink = rtw_mesh_plink_get_no_estab_by_idx(padapter, idx - asoc_list_num);
5867
}
5868
#endif /* CONFIG_RTW_MESH */
5869
5870
if ((!MLME_IS_MESH(padapter) && !psta)
5871
#ifdef CONFIG_RTW_MESH
5872
|| (MLME_IS_MESH(padapter) && !plink)
5873
#endif
5874
) {
5875
if (DBG_DUMP_STATION)
5876
RTW_INFO(FUNC_NDEV_FMT" end with idx:%d\n", FUNC_NDEV_ARG(ndev), idx);
5877
ret = -ENOENT;
5878
goto exit;
5879
}
5880
5881
if (psta)
5882
_rtw_memcpy(mac, psta->cmn.mac_addr, ETH_ALEN);
5883
#ifdef CONFIG_RTW_MESH
5884
else
5885
_rtw_memcpy(mac, plink->addr, ETH_ALEN);
5886
#endif
5887
5888
sinfo->filled = 0;
5889
5890
if (psta) {
5891
sinfo->filled |= STATION_INFO_SIGNAL;
5892
sinfo->signal = translate_percentage_to_dbm(psta->cmn.rssi_stat.rssi);
5893
sinfo->filled |= STATION_INFO_INACTIVE_TIME;
5894
sinfo->inactive_time = rtw_get_passing_time_ms(psta->sta_stats.last_rx_time);
5895
}
5896
5897
#ifdef CONFIG_RTW_MESH
5898
if (MLME_IS_MESH(padapter))
5899
rtw_cfg80211_fill_mesh_only_sta_info(plink, psta, sinfo);
5900
#endif
5901
5902
exit:
5903
return ret;
5904
}
5905
5906
static int cfg80211_rtw_change_bss(struct wiphy *wiphy, struct net_device *ndev,
5907
struct bss_parameters *params)
5908
{
5909
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
5910
/*
5911
RTW_INFO("use_cts_prot=%d\n", params->use_cts_prot);
5912
RTW_INFO("use_short_preamble=%d\n", params->use_short_preamble);
5913
RTW_INFO("use_short_slot_time=%d\n", params->use_short_slot_time);
5914
RTW_INFO("ap_isolate=%d\n", params->ap_isolate);
5915
5916
RTW_INFO("basic_rates_len=%d\n", params->basic_rates_len);
5917
for(i = 0; i < params->basic_rates_len; i++)
5918
RTW_INFO("basic_rates=%d\n", params->basic_rates[i]);
5919
*/
5920
return 0;
5921
5922
}
5923
5924
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
5925
static int cfg80211_rtw_set_txq_params(struct wiphy *wiphy
5926
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
5927
, struct net_device *ndev
5928
#endif
5929
, struct ieee80211_txq_params *params)
5930
{
5931
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
5932
_adapter *padapter = rtw_netdev_priv(ndev);
5933
#else
5934
_adapter *padapter = wiphy_to_adapter(wiphy);
5935
#endif
5936
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5937
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5938
u8 ac, AIFS, ECWMin, ECWMax, aSifsTime;
5939
u16 TXOP;
5940
u8 shift_count = 0;
5941
u32 acParm;
5942
5943
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
5944
ac = params->ac;
5945
#else
5946
ac = params->queue;
5947
#endif
5948
5949
switch (ac) {
5950
case NL80211_TXQ_Q_VO:
5951
ac = XMIT_VO_QUEUE;
5952
break;
5953
5954
case NL80211_TXQ_Q_VI:
5955
ac = XMIT_VI_QUEUE;
5956
break;
5957
5958
case NL80211_TXQ_Q_BE:
5959
ac = XMIT_BE_QUEUE;
5960
break;
5961
5962
case NL80211_TXQ_Q_BK:
5963
ac = XMIT_BK_QUEUE;
5964
break;
5965
5966
default:
5967
break;
5968
}
5969
5970
#if 0
5971
RTW_INFO("ac=%d\n", ac);
5972
RTW_INFO("txop=%u\n", params->txop);
5973
RTW_INFO("cwmin=%u\n", params->cwmin);
5974
RTW_INFO("cwmax=%u\n", params->cwmax);
5975
RTW_INFO("aifs=%u\n", params->aifs);
5976
#endif
5977
5978
if (is_supported_5g(pmlmeext->cur_wireless_mode) ||
5979
(pmlmeext->cur_wireless_mode & WIRELESS_11_24N))
5980
aSifsTime = 16;
5981
else
5982
aSifsTime = 10;
5983
5984
AIFS = params->aifs * pmlmeinfo->slotTime + aSifsTime;
5985
5986
while ((params->cwmin + 1) >> shift_count != 1) {
5987
shift_count++;
5988
if (shift_count == 15)
5989
break;
5990
}
5991
5992
ECWMin = shift_count;
5993
5994
shift_count = 0;
5995
while ((params->cwmax + 1) >> shift_count != 1) {
5996
shift_count++;
5997
if (shift_count == 15)
5998
break;
5999
}
6000
6001
ECWMax = shift_count;
6002
6003
TXOP = le16_to_cpu(params->txop);
6004
6005
acParm = AIFS | (ECWMin << 8) | (ECWMax << 12) | (TXOP << 16);
6006
6007
set_txq_params_cmd(padapter, acParm, ac);
6008
6009
return 0;
6010
}
6011
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29)) */
6012
6013
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
6014
static int cfg80211_rtw_set_channel(struct wiphy *wiphy
6015
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6016
, struct net_device *ndev
6017
#endif
6018
, struct ieee80211_channel *chan, enum nl80211_channel_type channel_type)
6019
{
6020
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6021
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
6022
#else
6023
_adapter *padapter = wiphy_to_adapter(wiphy);
6024
#endif
6025
int chan_target = (u8) ieee80211_frequency_to_channel(chan->center_freq);
6026
int chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6027
int chan_width = CHANNEL_WIDTH_20;
6028
6029
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
6030
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6031
#endif
6032
6033
switch (channel_type) {
6034
case NL80211_CHAN_NO_HT:
6035
case NL80211_CHAN_HT20:
6036
chan_width = CHANNEL_WIDTH_20;
6037
chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6038
break;
6039
case NL80211_CHAN_HT40MINUS:
6040
chan_width = CHANNEL_WIDTH_40;
6041
chan_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
6042
break;
6043
case NL80211_CHAN_HT40PLUS:
6044
chan_width = CHANNEL_WIDTH_40;
6045
chan_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
6046
break;
6047
default:
6048
chan_width = CHANNEL_WIDTH_20;
6049
chan_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6050
break;
6051
}
6052
6053
RTW_INFO(FUNC_ADPT_FMT" ch:%d bw:%d, offset:%d\n"
6054
, FUNC_ADPT_ARG(padapter), chan_target, chan_width, chan_offset);
6055
6056
rtw_set_chbw_cmd(padapter, chan_target, chan_width, chan_offset, RTW_CMDF_WAIT_ACK);
6057
6058
return 0;
6059
}
6060
#endif /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))*/
6061
6062
static int cfg80211_rtw_set_monitor_channel(struct wiphy *wiphy
6063
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
6064
, struct cfg80211_chan_def *chandef
6065
#else
6066
, struct ieee80211_channel *chan
6067
, enum nl80211_channel_type channel_type
6068
#endif
6069
)
6070
{
6071
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
6072
struct ieee80211_channel *chan = chandef->chan;
6073
#endif
6074
6075
_adapter *padapter = wiphy_to_adapter(wiphy);
6076
int target_channal = chan->hw_value;
6077
int target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6078
int target_width = CHANNEL_WIDTH_20;
6079
6080
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
6081
#ifdef CONFIG_DEBUG_CFG80211
6082
RTW_INFO("center_freq %u Mhz ch %u width %u freq1 %u freq2 %u\n"
6083
, chan->center_freq
6084
, chan->hw_value
6085
, chandef->width
6086
, chandef->center_freq1
6087
, chandef->center_freq2);
6088
#endif /* CONFIG_DEBUG_CFG80211 */
6089
6090
switch (chandef->width) {
6091
case NL80211_CHAN_WIDTH_20_NOHT:
6092
case NL80211_CHAN_WIDTH_20:
6093
target_width = CHANNEL_WIDTH_20;
6094
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6095
break;
6096
case NL80211_CHAN_WIDTH_40:
6097
target_width = CHANNEL_WIDTH_40;
6098
if (chandef->center_freq1 > chan->center_freq)
6099
target_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
6100
else
6101
target_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
6102
break;
6103
case NL80211_CHAN_WIDTH_80:
6104
target_width = CHANNEL_WIDTH_80;
6105
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6106
break;
6107
case NL80211_CHAN_WIDTH_80P80:
6108
target_width = CHANNEL_WIDTH_80_80;
6109
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6110
break;
6111
case NL80211_CHAN_WIDTH_160:
6112
target_width = CHANNEL_WIDTH_160;
6113
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6114
break;
6115
6116
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
6117
case NL80211_CHAN_WIDTH_5:
6118
case NL80211_CHAN_WIDTH_10:
6119
#endif
6120
default:
6121
target_width = CHANNEL_WIDTH_20;
6122
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6123
break;
6124
}
6125
#else
6126
#ifdef CONFIG_DEBUG_CFG80211
6127
RTW_INFO("center_freq %u Mhz ch %u channel_type %u\n"
6128
, chan->center_freq
6129
, chan->hw_value
6130
, channel_type);
6131
#endif /* CONFIG_DEBUG_CFG80211 */
6132
6133
switch (channel_type) {
6134
case NL80211_CHAN_NO_HT:
6135
case NL80211_CHAN_HT20:
6136
target_width = CHANNEL_WIDTH_20;
6137
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6138
break;
6139
case NL80211_CHAN_HT40MINUS:
6140
target_width = CHANNEL_WIDTH_40;
6141
target_offset = HAL_PRIME_CHNL_OFFSET_UPPER;
6142
break;
6143
case NL80211_CHAN_HT40PLUS:
6144
target_width = CHANNEL_WIDTH_40;
6145
target_offset = HAL_PRIME_CHNL_OFFSET_LOWER;
6146
break;
6147
default:
6148
target_width = CHANNEL_WIDTH_20;
6149
target_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
6150
break;
6151
}
6152
#endif
6153
RTW_INFO(FUNC_ADPT_FMT" ch:%d bw:%d, offset:%d\n"
6154
, FUNC_ADPT_ARG(padapter), target_channal, target_width, target_offset);
6155
6156
rtw_set_chbw_cmd(padapter, target_channal, target_width, target_offset, RTW_CMDF_WAIT_ACK);
6157
6158
return 0;
6159
}
6160
/*
6161
static int cfg80211_rtw_auth(struct wiphy *wiphy, struct net_device *ndev,
6162
struct cfg80211_auth_request *req)
6163
{
6164
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6165
6166
return 0;
6167
}
6168
6169
static int cfg80211_rtw_assoc(struct wiphy *wiphy, struct net_device *ndev,
6170
struct cfg80211_assoc_request *req)
6171
{
6172
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(ndev));
6173
6174
return 0;
6175
}
6176
*/
6177
#endif /* CONFIG_AP_MODE */
6178
6179
void rtw_cfg80211_external_auth_request(_adapter *padapter, union recv_frame *rframe)
6180
{
6181
struct rtw_external_auth_params params;
6182
struct wireless_dev *wdev = padapter->rtw_wdev;
6183
struct net_device *netdev = wdev_to_ndev(wdev);
6184
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6185
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6186
6187
u8 frame[256] = { 0 };
6188
uint frame_len = 24;
6189
s32 freq = 0;
6190
6191
/* rframe, in this case is null point */
6192
6193
freq = rtw_ch2freq(pmlmeext->cur_channel);
6194
6195
#ifdef CONFIG_DEBUG_CFG80211
6196
RTW_INFO(FUNC_ADPT_FMT": freq(%d, %d)\n", FUNC_ADPT_ARG(padapter), freq);
6197
#endif
6198
6199
#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE)
6200
params.action = EXTERNAL_AUTH_START;
6201
_rtw_memcpy(params.bssid, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6202
params.ssid.ssid_len = pmlmeinfo->network.Ssid.SsidLength;
6203
_rtw_memcpy(params.ssid.ssid, pmlmeinfo->network.Ssid.Ssid,
6204
pmlmeinfo->network.Ssid.SsidLength);
6205
params.key_mgmt_suite = 0x8ac0f00;
6206
6207
cfg80211_external_auth_request(netdev,
6208
(struct cfg80211_external_auth_params *)&params, GFP_ATOMIC);
6209
#elif (KERNEL_VERSION(2, 6, 37) <= LINUX_VERSION_CODE)
6210
set_frame_sub_type(frame, WIFI_AUTH);
6211
6212
_rtw_memcpy(frame + 4, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6213
_rtw_memcpy(frame + 10, adapter_mac_addr(padapter), ETH_ALEN);
6214
_rtw_memcpy(frame + 16, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
6215
RTW_PUT_LE32((frame + 18), 0x8ac0f00);
6216
6217
if (pmlmeinfo->network.Ssid.SsidLength) {
6218
*(frame + 23) = pmlmeinfo->network.Ssid.SsidLength;
6219
_rtw_memcpy(frame + 24, pmlmeinfo->network.Ssid.Ssid,
6220
pmlmeinfo->network.Ssid.SsidLength);
6221
frame_len = 24 + pmlmeinfo->network.Ssid.SsidLength;
6222
}
6223
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6224
#endif
6225
}
6226
6227
void rtw_cfg80211_rx_probe_request(_adapter *adapter, union recv_frame *rframe)
6228
{
6229
struct wireless_dev *wdev = adapter->rtw_wdev;
6230
u8 *frame = get_recvframe_data(rframe);
6231
uint frame_len = rframe->u.hdr.len;
6232
s32 freq;
6233
u8 ch, sch = rtw_get_oper_ch(adapter);
6234
6235
ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
6236
freq = rtw_ch2freq(ch);
6237
6238
#ifdef CONFIG_DEBUG_CFG80211
6239
RTW_INFO("RTW_Rx: probe request, ch=%d(%d), ta="MAC_FMT"\n"
6240
, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
6241
#endif
6242
6243
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)) || defined(COMPAT_KERNEL_RELEASE)
6244
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6245
#else
6246
cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
6247
#endif
6248
}
6249
6250
void rtw_cfg80211_rx_action_p2p(_adapter *adapter, union recv_frame *rframe)
6251
{
6252
struct wireless_dev *wdev = adapter->rtw_wdev;
6253
u8 *frame = get_recvframe_data(rframe);
6254
uint frame_len = rframe->u.hdr.len;
6255
s32 freq;
6256
u8 ch, sch = rtw_get_oper_ch(adapter);
6257
u8 category, action;
6258
int type;
6259
6260
ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
6261
freq = rtw_ch2freq(ch);
6262
6263
RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
6264
, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
6265
#ifdef CONFIG_P2P
6266
type = rtw_p2p_check_frames(adapter, frame, frame_len, _FALSE);
6267
if (type >= 0)
6268
goto indicate;
6269
#endif
6270
rtw_action_frame_parse(frame, frame_len, &category, &action);
6271
RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
6272
#ifdef CONFIG_P2P
6273
indicate:
6274
#endif
6275
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6276
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6277
#else
6278
cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
6279
#endif
6280
}
6281
6282
void rtw_cfg80211_rx_p2p_action_public(_adapter *adapter, union recv_frame *rframe)
6283
{
6284
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
6285
struct wireless_dev *wdev = adapter->rtw_wdev;
6286
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(adapter);
6287
u8 *frame = get_recvframe_data(rframe);
6288
uint frame_len = rframe->u.hdr.len;
6289
s32 freq;
6290
u8 ch, sch = rtw_get_oper_ch(adapter);
6291
u8 category, action;
6292
int type;
6293
6294
ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
6295
freq = rtw_ch2freq(ch);
6296
6297
RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
6298
, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
6299
#ifdef CONFIG_P2P
6300
type = rtw_p2p_check_frames(adapter, frame, frame_len, _FALSE);
6301
if (type >= 0) {
6302
switch (type) {
6303
case P2P_GO_NEGO_CONF:
6304
if (0) {
6305
RTW_INFO(FUNC_ADPT_FMT" Nego confirm. state=%u, status=%u, iaddr="MAC_FMT"\n"
6306
, FUNC_ADPT_ARG(adapter), pwdev_priv->nego_info.state, pwdev_priv->nego_info.status
6307
, MAC_ARG(pwdev_priv->nego_info.iface_addr));
6308
}
6309
if (pwdev_priv->nego_info.state == 2
6310
&& pwdev_priv->nego_info.status == 0
6311
&& rtw_check_invalid_mac_address(pwdev_priv->nego_info.iface_addr, _FALSE) == _FALSE
6312
) {
6313
_adapter *intended_iface = dvobj_get_adapter_by_addr(dvobj, pwdev_priv->nego_info.iface_addr);
6314
6315
if (intended_iface) {
6316
RTW_INFO(FUNC_ADPT_FMT" Nego confirm. Allow only "ADPT_FMT" to scan for 2000 ms\n"
6317
, FUNC_ADPT_ARG(adapter), ADPT_ARG(intended_iface));
6318
/* allow only intended_iface to do scan for 2000 ms */
6319
rtw_mi_set_scan_deny(adapter, 2000);
6320
rtw_clear_scan_deny(intended_iface);
6321
}
6322
}
6323
break;
6324
case P2P_PROVISION_DISC_RESP:
6325
case P2P_INVIT_RESP:
6326
rtw_clear_scan_deny(adapter);
6327
#if !RTW_P2P_GROUP_INTERFACE
6328
rtw_mi_buddy_set_scan_deny(adapter, 2000);
6329
#endif
6330
break;
6331
}
6332
goto indicate;
6333
}
6334
#endif
6335
rtw_action_frame_parse(frame, frame_len, &category, &action);
6336
RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
6337
#ifdef CONFIG_P2P
6338
indicate:
6339
#endif
6340
#if defined(RTW_DEDICATED_P2P_DEVICE)
6341
if (rtw_cfg80211_redirect_pd_wdev(dvobj_to_wiphy(dvobj), get_ra(frame), &wdev))
6342
if (0)
6343
RTW_INFO("redirect to pd_wdev:%p\n", wdev);
6344
#endif
6345
6346
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6347
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6348
#else
6349
cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
6350
#endif
6351
}
6352
6353
void rtw_cfg80211_rx_action(_adapter *adapter, union recv_frame *rframe, const char *msg)
6354
{
6355
struct wireless_dev *wdev = adapter->rtw_wdev;
6356
u8 *frame = get_recvframe_data(rframe);
6357
uint frame_len = rframe->u.hdr.len;
6358
s32 freq;
6359
u8 ch, sch = rtw_get_oper_ch(adapter);
6360
u8 category, action;
6361
int type = -1;
6362
6363
ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
6364
freq = rtw_ch2freq(ch);
6365
6366
RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
6367
, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
6368
6369
#ifdef CONFIG_RTW_MESH
6370
if (MLME_IS_MESH(adapter)) {
6371
type = rtw_mesh_check_frames_rx(adapter, frame, frame_len);
6372
if (type >= 0)
6373
goto indicate;
6374
}
6375
#endif
6376
rtw_action_frame_parse(frame, frame_len, &category, &action);
6377
if (category == RTW_WLAN_CATEGORY_PUBLIC) {
6378
if (action == ACT_PUBLIC_GAS_INITIAL_REQ) {
6379
rtw_mi_set_scan_deny(adapter, 200);
6380
rtw_mi_scan_abort(adapter, _FALSE); /*rtw_scan_abort_no_wait*/
6381
}
6382
}
6383
#ifdef CONFIG_RTW_MESH
6384
indicate:
6385
#endif
6386
6387
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6388
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6389
#else
6390
cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
6391
#endif
6392
6393
if (type == -1) {
6394
if (msg)
6395
RTW_INFO("RTW_Rx:%s\n", msg);
6396
else
6397
RTW_INFO("RTW_Rx:category(%u), action(%u)\n", category, action);
6398
}
6399
}
6400
6401
#ifdef CONFIG_RTW_80211K
6402
void rtw_cfg80211_rx_rrm_action(_adapter *adapter, union recv_frame *rframe)
6403
{
6404
struct wireless_dev *wdev = adapter->rtw_wdev;
6405
u8 *frame = get_recvframe_data(rframe);
6406
uint frame_len = rframe->u.hdr.len;
6407
s32 freq;
6408
u8 ch, sch = rtw_get_oper_ch(adapter);
6409
6410
ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
6411
freq = rtw_ch2freq(ch);
6412
6413
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6414
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6415
#else
6416
cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
6417
#endif
6418
RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n"
6419
, ch, sch, MAC_ARG(get_addr2_ptr(frame)));
6420
}
6421
#endif /* CONFIG_RTW_80211K */
6422
6423
void rtw_cfg80211_rx_mframe(_adapter *adapter, union recv_frame *rframe, const char *msg)
6424
{
6425
struct wireless_dev *wdev = adapter->rtw_wdev;
6426
u8 *frame = get_recvframe_data(rframe);
6427
uint frame_len = rframe->u.hdr.len;
6428
s32 freq;
6429
u8 ch, sch = rtw_get_oper_ch(adapter);
6430
6431
ch = rframe->u.hdr.attrib.ch ? rframe->u.hdr.attrib.ch : sch;
6432
freq = rtw_ch2freq(ch);
6433
6434
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
6435
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, frame_len, GFP_ATOMIC);
6436
#else
6437
cfg80211_rx_action(adapter->pnetdev, freq, frame, frame_len, GFP_ATOMIC);
6438
#endif
6439
6440
RTW_INFO("RTW_Rx:ch=%d(%d), ta="MAC_FMT"\n", ch, sch, MAC_ARG(get_addr2_ptr(frame)));
6441
if (!rtw_sae_preprocess(adapter, frame, frame_len, _FALSE)) {
6442
if (msg)
6443
RTW_INFO("RTW_Rx:%s\n", msg);
6444
else
6445
RTW_INFO("RTW_Rx:frame_control:0x%02x\n", le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)rframe)->frame_ctl));
6446
}
6447
}
6448
6449
#ifdef CONFIG_P2P
6450
void rtw_cfg80211_issue_p2p_provision_request(_adapter *padapter, const u8 *buf, size_t len)
6451
{
6452
u16 wps_devicepassword_id = 0x0000;
6453
uint wps_devicepassword_id_len = 0;
6454
u8 wpsie[255] = { 0x00 }, p2p_ie[255] = { 0x00 };
6455
uint p2p_ielen = 0;
6456
uint wpsielen = 0;
6457
u32 devinfo_contentlen = 0;
6458
u8 devinfo_content[64] = { 0x00 };
6459
u16 capability = 0;
6460
uint capability_len = 0;
6461
6462
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
6463
u8 action = P2P_PUB_ACTION_ACTION;
6464
u8 dialogToken = 1;
6465
u32 p2poui = cpu_to_be32(P2POUI);
6466
u8 oui_subtype = P2P_PROVISION_DISC_REQ;
6467
u32 p2pielen = 0;
6468
#ifdef CONFIG_WFD
6469
u32 wfdielen = 0;
6470
#endif
6471
6472
struct xmit_frame *pmgntframe;
6473
struct pkt_attrib *pattrib;
6474
unsigned char *pframe;
6475
struct rtw_ieee80211_hdr *pwlanhdr;
6476
unsigned short *fctrl;
6477
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
6478
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
6479
6480
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6481
u8 *frame_body = (unsigned char *)(buf + sizeof(struct rtw_ieee80211_hdr_3addr));
6482
size_t frame_body_len = len - sizeof(struct rtw_ieee80211_hdr_3addr);
6483
6484
6485
RTW_INFO("[%s] In\n", __FUNCTION__);
6486
6487
/* prepare for building provision_request frame */
6488
_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerIFAddr, GetAddr1Ptr(buf), ETH_ALEN);
6489
_rtw_memcpy(pwdinfo->tx_prov_disc_info.peerDevAddr, GetAddr1Ptr(buf), ETH_ALEN);
6490
6491
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6492
6493
rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
6494
rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
6495
wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
6496
6497
switch (wps_devicepassword_id) {
6498
case WPS_DPID_PIN:
6499
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_LABEL;
6500
break;
6501
case WPS_DPID_USER_SPEC:
6502
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_DISPLYA;
6503
break;
6504
case WPS_DPID_MACHINE_SPEC:
6505
break;
6506
case WPS_DPID_REKEY:
6507
break;
6508
case WPS_DPID_PBC:
6509
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_PUSH_BUTTON;
6510
break;
6511
case WPS_DPID_REGISTRAR_SPEC:
6512
pwdinfo->tx_prov_disc_info.wps_config_method_request = WPS_CM_KEYPAD;
6513
break;
6514
default:
6515
break;
6516
}
6517
6518
6519
if (rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, frame_body_len - _PUBLIC_ACTION_IE_OFFSET_, p2p_ie, &p2p_ielen)) {
6520
6521
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_DEVICE_INFO, devinfo_content, &devinfo_contentlen);
6522
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&capability, &capability_len);
6523
6524
}
6525
6526
6527
/* start to build provision_request frame */
6528
_rtw_memset(wpsie, 0, sizeof(wpsie));
6529
_rtw_memset(p2p_ie, 0, sizeof(p2p_ie));
6530
p2p_ielen = 0;
6531
6532
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
6533
if (pmgntframe == NULL)
6534
return;
6535
6536
6537
/* update attribute */
6538
pattrib = &pmgntframe->attrib;
6539
update_mgntframe_attrib(padapter, pattrib);
6540
6541
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
6542
6543
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
6544
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
6545
6546
fctrl = &(pwlanhdr->frame_ctl);
6547
*(fctrl) = 0;
6548
6549
_rtw_memcpy(pwlanhdr->addr1, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
6550
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
6551
_rtw_memcpy(pwlanhdr->addr3, pwdinfo->tx_prov_disc_info.peerDevAddr, ETH_ALEN);
6552
6553
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
6554
pmlmeext->mgnt_seq++;
6555
set_frame_sub_type(pframe, WIFI_ACTION);
6556
6557
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
6558
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
6559
6560
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
6561
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
6562
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
6563
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
6564
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
6565
6566
6567
/* build_prov_disc_request_p2p_ie */
6568
/* P2P OUI */
6569
p2pielen = 0;
6570
p2p_ie[p2pielen++] = 0x50;
6571
p2p_ie[p2pielen++] = 0x6F;
6572
p2p_ie[p2pielen++] = 0x9A;
6573
p2p_ie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
6574
6575
/* Commented by Albert 20110301 */
6576
/* According to the P2P Specification, the provision discovery request frame should contain 3 P2P attributes */
6577
/* 1. P2P Capability */
6578
/* 2. Device Info */
6579
/* 3. Group ID ( When joining an operating P2P Group ) */
6580
6581
/* P2P Capability ATTR */
6582
/* Type: */
6583
p2p_ie[p2pielen++] = P2P_ATTR_CAPABILITY;
6584
6585
/* Length: */
6586
/* *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 0x0002 ); */
6587
RTW_PUT_LE16(p2p_ie + p2pielen, 0x0002);
6588
p2pielen += 2;
6589
6590
/* Value: */
6591
/* Device Capability Bitmap, 1 byte */
6592
/* Group Capability Bitmap, 1 byte */
6593
_rtw_memcpy(p2p_ie + p2pielen, &capability, 2);
6594
p2pielen += 2;
6595
6596
6597
/* Device Info ATTR */
6598
/* Type: */
6599
p2p_ie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
6600
6601
/* Length: */
6602
/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
6603
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
6604
/* *(u16*) ( p2pie + p2pielen ) = cpu_to_le16( 21 + pwdinfo->device_name_len ); */
6605
RTW_PUT_LE16(p2p_ie + p2pielen, devinfo_contentlen);
6606
p2pielen += 2;
6607
6608
/* Value: */
6609
_rtw_memcpy(p2p_ie + p2pielen, devinfo_content, devinfo_contentlen);
6610
p2pielen += devinfo_contentlen;
6611
6612
6613
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2p_ie, &p2p_ielen);
6614
/* p2pielen = build_prov_disc_request_p2p_ie( pwdinfo, pframe, NULL, 0, pwdinfo->tx_prov_disc_info.peerDevAddr); */
6615
/* pframe += p2pielen; */
6616
pattrib->pktlen += p2p_ielen;
6617
6618
wpsielen = 0;
6619
/* WPS OUI */
6620
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
6621
wpsielen += 4;
6622
6623
/* WPS version */
6624
/* Type: */
6625
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
6626
wpsielen += 2;
6627
6628
/* Length: */
6629
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
6630
wpsielen += 2;
6631
6632
/* Value: */
6633
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
6634
6635
/* Config Method */
6636
/* Type: */
6637
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
6638
wpsielen += 2;
6639
6640
/* Length: */
6641
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
6642
wpsielen += 2;
6643
6644
/* Value: */
6645
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
6646
wpsielen += 2;
6647
6648
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
6649
6650
6651
#ifdef CONFIG_WFD
6652
wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
6653
pframe += wfdielen;
6654
pattrib->pktlen += wfdielen;
6655
#endif
6656
6657
pattrib->last_txcmdsz = pattrib->pktlen;
6658
6659
/* dump_mgntframe(padapter, pmgntframe); */
6660
if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS)
6661
RTW_INFO("%s, ack to\n", __func__);
6662
6663
#if 0
6664
if(wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC) {
6665
RTW_INFO("waiting for p2p peer key-in PIN CODE\n");
6666
rtw_msleep_os(15000); /* 15 sec for key in PIN CODE, workaround for GS2 before issuing Nego Req. */
6667
}
6668
#endif
6669
6670
}
6671
6672
#ifdef CONFIG_RTW_80211R
6673
static s32 cfg80211_rtw_update_ft_ies(struct wiphy *wiphy,
6674
struct net_device *ndev,
6675
struct cfg80211_update_ft_ies_params *ftie)
6676
{
6677
_adapter *padapter = NULL;
6678
struct mlme_priv *pmlmepriv = NULL;
6679
struct ft_roam_info *pft_roam = NULL;
6680
_irqL irqL;
6681
u8 *p;
6682
u8 *pie = NULL;
6683
u32 ie_len = 0;
6684
6685
if (ndev == NULL)
6686
return -EINVAL;
6687
6688
padapter = (_adapter *)rtw_netdev_priv(ndev);
6689
pmlmepriv = &(padapter->mlmepriv);
6690
pft_roam = &(pmlmepriv->ft_roam);
6691
6692
p = (u8 *)ftie->ie;
6693
if (ftie->ie_len <= sizeof(pft_roam->updated_ft_ies)) {
6694
_enter_critical_bh(&pmlmepriv->lock, &irqL);
6695
_rtw_memcpy(pft_roam->updated_ft_ies, ftie->ie, ftie->ie_len);
6696
pft_roam->updated_ft_ies_len = ftie->ie_len;
6697
_exit_critical_bh(&pmlmepriv->lock, &irqL);
6698
} else {
6699
RTW_ERR("FTIEs parsing fail!\n");
6700
return -EINVAL;
6701
}
6702
6703
if (rtw_ft_roam_status(padapter, RTW_FT_AUTHENTICATED_STA)) {
6704
RTW_PRINT("auth success, start reassoc\n");
6705
rtw_ft_lock_set_status(padapter, RTW_FT_ASSOCIATING_STA, &irqL);
6706
start_clnt_assoc(padapter);
6707
}
6708
6709
return 0;
6710
}
6711
#endif
6712
6713
inline void rtw_cfg80211_set_is_roch(_adapter *adapter, bool val)
6714
{
6715
adapter->cfg80211_wdinfo.is_ro_ch = val;
6716
rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
6717
}
6718
6719
inline bool rtw_cfg80211_get_is_roch(_adapter *adapter)
6720
{
6721
return adapter->cfg80211_wdinfo.is_ro_ch;
6722
}
6723
6724
inline bool rtw_cfg80211_is_ro_ch_once(_adapter *adapter)
6725
{
6726
return adapter->cfg80211_wdinfo.last_ro_ch_time ? 1 : 0;
6727
}
6728
6729
inline void rtw_cfg80211_set_last_ro_ch_time(_adapter *adapter)
6730
{
6731
adapter->cfg80211_wdinfo.last_ro_ch_time = rtw_get_current_time();
6732
6733
if (!adapter->cfg80211_wdinfo.last_ro_ch_time)
6734
adapter->cfg80211_wdinfo.last_ro_ch_time++;
6735
}
6736
6737
inline s32 rtw_cfg80211_get_last_ro_ch_passing_ms(_adapter *adapter)
6738
{
6739
return rtw_get_passing_time_ms(adapter->cfg80211_wdinfo.last_ro_ch_time);
6740
}
6741
6742
static s32 cfg80211_rtw_remain_on_channel(struct wiphy *wiphy,
6743
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6744
struct wireless_dev *wdev,
6745
#else
6746
struct net_device *ndev,
6747
#endif
6748
struct ieee80211_channel *channel,
6749
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
6750
enum nl80211_channel_type channel_type,
6751
#endif
6752
unsigned int duration, u64 *cookie)
6753
{
6754
s32 err = 0;
6755
u8 remain_ch = (u8) ieee80211_frequency_to_channel(channel->center_freq);
6756
_adapter *padapter = NULL;
6757
struct rtw_wdev_priv *pwdev_priv;
6758
struct wifidirect_info *pwdinfo;
6759
struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
6760
#ifdef CONFIG_CONCURRENT_MODE
6761
u8 is_p2p_find = _FALSE;
6762
#endif
6763
6764
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6765
#if defined(RTW_DEDICATED_P2P_DEVICE)
6766
if (wdev == wiphy_to_pd_wdev(wiphy))
6767
padapter = wiphy_to_adapter(wiphy);
6768
else
6769
#endif
6770
if (wdev_to_ndev(wdev))
6771
padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
6772
else {
6773
err = -EINVAL;
6774
goto exit;
6775
}
6776
#else
6777
struct wireless_dev *wdev;
6778
6779
if (ndev == NULL) {
6780
err = -EINVAL;
6781
goto exit;
6782
}
6783
padapter = (_adapter *)rtw_netdev_priv(ndev);
6784
wdev = ndev_to_wdev(ndev);
6785
#endif
6786
6787
pwdev_priv = adapter_wdev_data(padapter);
6788
pwdinfo = &padapter->wdinfo;
6789
pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
6790
#ifdef CONFIG_CONCURRENT_MODE
6791
is_p2p_find = (duration < (pwdinfo->ext_listen_interval)) ? _TRUE : _FALSE;
6792
#endif
6793
6794
*cookie = ATOMIC_INC_RETURN(&pcfg80211_wdinfo->ro_ch_cookie_gen);
6795
6796
RTW_INFO(FUNC_ADPT_FMT"%s ch:%u duration:%d, cookie:0x%llx\n"
6797
, FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
6798
, remain_ch, duration, *cookie);
6799
6800
if (rtw_chset_search_ch(adapter_to_chset(padapter), remain_ch) < 0) {
6801
RTW_WARN(FUNC_ADPT_FMT" invalid ch:%u\n", FUNC_ADPT_ARG(padapter), remain_ch);
6802
err = -EFAULT;
6803
goto exit;
6804
}
6805
6806
#ifdef CONFIG_MP_INCLUDED
6807
if (rtw_mp_mode_check(padapter)) {
6808
RTW_INFO("MP mode block remain_on_channel request\n");
6809
err = -EFAULT;
6810
goto exit;
6811
}
6812
#endif
6813
6814
if (_FAIL == rtw_pwr_wakeup(padapter)) {
6815
err = -EFAULT;
6816
goto exit;
6817
}
6818
6819
rtw_scan_abort(padapter);
6820
#ifdef CONFIG_CONCURRENT_MODE
6821
/*don't scan_abort during p2p_listen.*/
6822
if (is_p2p_find)
6823
rtw_mi_buddy_scan_abort(padapter, _TRUE);
6824
#endif /*CONFIG_CONCURRENT_MODE*/
6825
6826
if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
6827
_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
6828
p2p_cancel_roch_cmd(padapter, 0, NULL, RTW_CMDF_WAIT_ACK);
6829
}
6830
6831
/* if(!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) && !rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) */
6832
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
6833
#if defined(CONFIG_ANDROID) && !defined(RTW_SINGLE_WIPHY)
6834
&& (!is_primary_adapter(padapter))
6835
/*wlan0 can't be p2p device in CONFIG_ANDROID */
6836
#endif
6837
){
6838
rtw_p2p_enable(padapter, P2P_ROLE_DEVICE);
6839
padapter->wdinfo.listen_channel = remain_ch;
6840
RTW_INFO(FUNC_ADPT_FMT" init listen_channel %u\n"
6841
, FUNC_ADPT_ARG(padapter), padapter->wdinfo.listen_channel);
6842
} else if (rtw_p2p_chk_state(pwdinfo , P2P_STATE_LISTEN)
6843
&& (time_after_eq(rtw_get_current_time(), pwdev_priv->probe_resp_ie_update_time)
6844
&& rtw_get_passing_time_ms(pwdev_priv->probe_resp_ie_update_time) < 50)
6845
) {
6846
if (padapter->wdinfo.listen_channel != remain_ch) {
6847
padapter->wdinfo.listen_channel = remain_ch;
6848
RTW_INFO(FUNC_ADPT_FMT" update listen_channel %u\n"
6849
, FUNC_ADPT_ARG(padapter), padapter->wdinfo.listen_channel);
6850
}
6851
} else {
6852
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6853
#ifdef CONFIG_DEBUG_CFG80211
6854
RTW_INFO("%s, role=%d, p2p_state=%d\n", __func__, rtw_p2p_role(pwdinfo), rtw_p2p_state(pwdinfo));
6855
#endif
6856
}
6857
6858
rtw_p2p_set_state(pwdinfo, P2P_STATE_LISTEN);
6859
6860
#ifdef RTW_ROCH_DURATION_ENLARGE
6861
if (duration < 400)
6862
duration = duration * 3; /* extend from exper */
6863
#endif
6864
6865
#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE)
6866
if (rtw_mi_check_status(padapter, MI_LINKED)) {
6867
if (is_p2p_find) /* p2p_find , duration<1000 */
6868
duration = duration + pwdinfo->ext_listen_interval;
6869
else /* p2p_listen, duration=5000 */
6870
duration = pwdinfo->ext_listen_interval + (pwdinfo->ext_listen_interval / 4);
6871
}
6872
#endif /*defined (RTW_ROCH_BACK_OP) && defined(CONFIG_CONCURRENT_MODE) */
6873
6874
rtw_cfg80211_set_is_roch(padapter, _TRUE);
6875
pcfg80211_wdinfo->ro_ch_wdev = wdev;
6876
pcfg80211_wdinfo->remain_on_ch_cookie = *cookie;
6877
rtw_cfg80211_set_last_ro_ch_time(padapter);
6878
_rtw_memcpy(&pcfg80211_wdinfo->remain_on_ch_channel, channel, sizeof(struct ieee80211_channel));
6879
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
6880
pcfg80211_wdinfo->remain_on_ch_type = channel_type;
6881
#endif
6882
pcfg80211_wdinfo->restore_channel = rtw_get_oper_ch(padapter);
6883
6884
p2p_roch_cmd(padapter, *cookie, wdev, channel, pcfg80211_wdinfo->remain_on_ch_type,
6885
duration, RTW_CMDF_WAIT_ACK);
6886
6887
rtw_cfg80211_ready_on_channel(wdev, *cookie, channel, channel_type, duration, GFP_KERNEL);
6888
exit:
6889
return err;
6890
}
6891
6892
static s32 cfg80211_rtw_cancel_remain_on_channel(struct wiphy *wiphy,
6893
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6894
struct wireless_dev *wdev,
6895
#else
6896
struct net_device *ndev,
6897
#endif
6898
u64 cookie)
6899
{
6900
s32 err = 0;
6901
_adapter *padapter;
6902
struct rtw_wdev_priv *pwdev_priv;
6903
struct wifidirect_info *pwdinfo;
6904
struct cfg80211_wifidirect_info *pcfg80211_wdinfo;
6905
6906
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
6907
#if defined(RTW_DEDICATED_P2P_DEVICE)
6908
if (wdev == wiphy_to_pd_wdev(wiphy))
6909
padapter = wiphy_to_adapter(wiphy);
6910
else
6911
#endif
6912
if (wdev_to_ndev(wdev))
6913
padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
6914
else {
6915
err = -EINVAL;
6916
goto exit;
6917
}
6918
#else
6919
struct wireless_dev *wdev;
6920
6921
if (ndev == NULL) {
6922
err = -EINVAL;
6923
goto exit;
6924
}
6925
padapter = (_adapter *)rtw_netdev_priv(ndev);
6926
wdev = ndev_to_wdev(ndev);
6927
#endif
6928
6929
pwdev_priv = adapter_wdev_data(padapter);
6930
pwdinfo = &padapter->wdinfo;
6931
pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
6932
6933
RTW_INFO(FUNC_ADPT_FMT"%s cookie:0x%llx\n"
6934
, FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
6935
, cookie);
6936
6937
if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
6938
_cancel_timer_ex(&padapter->cfg80211_wdinfo.remain_on_ch_timer);
6939
p2p_cancel_roch_cmd(padapter, cookie, wdev, RTW_CMDF_WAIT_ACK);
6940
}
6941
6942
exit:
6943
return err;
6944
}
6945
6946
inline int rtw_cfg80211_iface_has_p2p_group_cap(_adapter *adapter)
6947
{
6948
#if RTW_P2P_GROUP_INTERFACE
6949
if (is_primary_adapter(adapter))
6950
return 0;
6951
#endif
6952
return 1;
6953
}
6954
6955
inline int rtw_cfg80211_is_p2p_scan(_adapter *adapter)
6956
{
6957
#if RTW_P2P_GROUP_INTERFACE
6958
if (rtw_cfg80211_iface_has_p2p_group_cap(adapter))
6959
#endif
6960
{
6961
struct wifidirect_info *wdinfo = &adapter->wdinfo;
6962
6963
return rtw_p2p_chk_state(wdinfo, P2P_STATE_SCAN)
6964
|| rtw_p2p_chk_state(wdinfo, P2P_STATE_FIND_PHASE_SEARCH);
6965
}
6966
6967
#if RTW_P2P_GROUP_INTERFACE
6968
#if defined(RTW_DEDICATED_P2P_DEVICE)
6969
if (wiphy_to_pd_wdev(adapter_to_wiphy(adapter))) /* pd_wdev exist */
6970
return rtw_cfg80211_is_scan_by_pd_wdev(adapter);
6971
#endif
6972
{
6973
/*
6974
* For 2 RTW_P2P_GROUP_INTERFACE cases:
6975
* 1. RTW_DEDICATED_P2P_DEVICE defined but upper layer don't use pd_wdev or
6976
* 2. RTW_DEDICATED_P2P_DEVICE not defined
6977
*/
6978
struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
6979
_irqL irqL;
6980
int is_p2p_scan = 0;
6981
6982
_enter_critical_bh(&wdev_data->scan_req_lock, &irqL);
6983
if (wdev_data->scan_request
6984
&& wdev_data->scan_request->n_ssids
6985
&& wdev_data->scan_request->ssids
6986
&& wdev_data->scan_request->ie
6987
) {
6988
if (_rtw_memcmp(wdev_data->scan_request->ssids[0].ssid, "DIRECT-", 7)
6989
&& rtw_get_p2p_ie((u8 *)wdev_data->scan_request->ie, wdev_data->scan_request->ie_len, NULL, NULL))
6990
is_p2p_scan = 1;
6991
}
6992
_exit_critical_bh(&wdev_data->scan_req_lock, &irqL);
6993
6994
return is_p2p_scan;
6995
}
6996
#endif
6997
}
6998
6999
#if defined(RTW_DEDICATED_P2P_DEVICE)
7000
int rtw_pd_iface_alloc(struct wiphy *wiphy, const char *name, struct wireless_dev **pd_wdev)
7001
{
7002
struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
7003
struct wireless_dev *wdev = NULL;
7004
struct rtw_netdev_priv_indicator *npi;
7005
_adapter *primary_adpt = wiphy_to_adapter(wiphy);
7006
int ret = 0;
7007
7008
if (wiphy_data->pd_wdev) {
7009
RTW_WARN(FUNC_WIPHY_FMT" pd_wdev already exists\n", FUNC_WIPHY_ARG(wiphy));
7010
ret = -EBUSY;
7011
goto exit;
7012
}
7013
7014
wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
7015
if (!wdev) {
7016
RTW_WARN(FUNC_WIPHY_FMT" allocate wdev fail\n", FUNC_WIPHY_ARG(wiphy));
7017
ret = -ENOMEM;
7018
goto exit;
7019
}
7020
7021
wdev->wiphy = wiphy;
7022
wdev->iftype = NL80211_IFTYPE_P2P_DEVICE;
7023
_rtw_memcpy(wdev->address, adapter_mac_addr(primary_adpt), ETH_ALEN);
7024
7025
wiphy_data->pd_wdev = wdev;
7026
*pd_wdev = wdev;
7027
7028
RTW_INFO(FUNC_WIPHY_FMT" pd_wdev:%p, addr="MAC_FMT" added\n"
7029
, FUNC_WIPHY_ARG(wiphy), wdev, MAC_ARG(wdev_address(wdev)));
7030
7031
exit:
7032
if (ret && wdev) {
7033
rtw_mfree((u8 *)wdev, sizeof(struct wireless_dev));
7034
wdev = NULL;
7035
}
7036
7037
return ret;
7038
}
7039
7040
void rtw_pd_iface_free(struct wiphy *wiphy)
7041
{
7042
struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);
7043
struct rtw_wiphy_data *wiphy_data = rtw_wiphy_priv(wiphy);
7044
u8 rtnl_lock_needed;
7045
7046
if (!wiphy_data->pd_wdev)
7047
goto exit;
7048
7049
RTW_INFO(FUNC_WIPHY_FMT" pd_wdev:%p, addr="MAC_FMT"\n"
7050
, FUNC_WIPHY_ARG(wiphy), wiphy_data->pd_wdev
7051
, MAC_ARG(wdev_address(wiphy_data->pd_wdev)));
7052
7053
rtnl_lock_needed = rtw_rtnl_lock_needed(dvobj);
7054
if (rtnl_lock_needed)
7055
rtnl_lock();
7056
cfg80211_unregister_wdev(wiphy_data->pd_wdev);
7057
if (rtnl_lock_needed)
7058
rtnl_unlock();
7059
7060
rtw_mfree((u8 *)wiphy_data->pd_wdev, sizeof(struct wireless_dev));
7061
wiphy_data->pd_wdev = NULL;
7062
7063
exit:
7064
return;
7065
}
7066
7067
static int cfg80211_rtw_start_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
7068
{
7069
_adapter *adapter = wiphy_to_adapter(wiphy);
7070
7071
RTW_INFO(FUNC_WIPHY_FMT" wdev=%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
7072
7073
rtw_p2p_enable(adapter, P2P_ROLE_DEVICE);
7074
return 0;
7075
}
7076
7077
static void cfg80211_rtw_stop_p2p_device(struct wiphy *wiphy, struct wireless_dev *wdev)
7078
{
7079
_adapter *adapter = wiphy_to_adapter(wiphy);
7080
7081
RTW_INFO(FUNC_WIPHY_FMT" wdev=%p\n", FUNC_WIPHY_ARG(wiphy), wdev);
7082
7083
if (rtw_cfg80211_is_p2p_scan(adapter))
7084
rtw_scan_abort(adapter);
7085
7086
rtw_p2p_enable(adapter, P2P_ROLE_DISABLE);
7087
}
7088
7089
inline int rtw_cfg80211_redirect_pd_wdev(struct wiphy *wiphy, u8 *ra, struct wireless_dev **wdev)
7090
{
7091
struct wireless_dev *pd_wdev = wiphy_to_pd_wdev(wiphy);
7092
7093
if (pd_wdev && pd_wdev != *wdev
7094
&& _rtw_memcmp(wdev_address(pd_wdev), ra, ETH_ALEN) == _TRUE
7095
) {
7096
*wdev = pd_wdev;
7097
return 1;
7098
}
7099
return 0;
7100
}
7101
7102
inline int rtw_cfg80211_is_scan_by_pd_wdev(_adapter *adapter)
7103
{
7104
struct wiphy *wiphy = adapter_to_wiphy(adapter);
7105
struct rtw_wdev_priv *wdev_data = adapter_wdev_data(adapter);
7106
struct wireless_dev *wdev = NULL;
7107
_irqL irqL;
7108
7109
_enter_critical_bh(&wdev_data->scan_req_lock, &irqL);
7110
if (wdev_data->scan_request)
7111
wdev = wdev_data->scan_request->wdev;
7112
_exit_critical_bh(&wdev_data->scan_req_lock, &irqL);
7113
7114
if (wdev && wdev == wiphy_to_pd_wdev(wiphy))
7115
return 1;
7116
7117
return 0;
7118
}
7119
#endif /* RTW_DEDICATED_P2P_DEVICE */
7120
#endif /* CONFIG_P2P */
7121
7122
inline void rtw_cfg80211_set_is_mgmt_tx(_adapter *adapter, u8 val)
7123
{
7124
struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
7125
7126
wdev_priv->is_mgmt_tx = val;
7127
rtw_mi_update_iface_status(&(adapter->mlmepriv), 0);
7128
}
7129
7130
inline u8 rtw_cfg80211_get_is_mgmt_tx(_adapter *adapter)
7131
{
7132
struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
7133
7134
return wdev_priv->is_mgmt_tx;
7135
}
7136
7137
static int _cfg80211_rtw_mgmt_tx(_adapter *padapter, u8 tx_ch, u8 no_cck, const u8 *buf, size_t len, int wait_ack)
7138
{
7139
struct xmit_frame *pmgntframe;
7140
struct pkt_attrib *pattrib;
7141
unsigned char *pframe;
7142
int ret = _FAIL;
7143
bool ack = _TRUE;
7144
struct rtw_ieee80211_hdr *pwlanhdr;
7145
#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
7146
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
7147
#endif
7148
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7149
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7150
u8 u_ch = rtw_mi_get_union_chan(padapter);
7151
u8 leave_op = 0;
7152
#ifdef CONFIG_P2P
7153
struct cfg80211_wifidirect_info *pcfg80211_wdinfo = &padapter->cfg80211_wdinfo;
7154
#ifdef CONFIG_CONCURRENT_MODE
7155
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
7156
#endif
7157
#endif
7158
7159
rtw_cfg80211_set_is_mgmt_tx(padapter, 1);
7160
7161
#ifdef CONFIG_BT_COEXIST
7162
rtw_btcoex_ScanNotify(padapter, _TRUE);
7163
#endif
7164
7165
#ifdef CONFIG_P2P
7166
if (rtw_cfg80211_get_is_roch(padapter) == _TRUE) {
7167
#ifdef CONFIG_CONCURRENT_MODE
7168
if (!check_fwstate(&padapter->mlmepriv, _FW_LINKED)) {
7169
RTW_INFO("%s, extend ro ch time\n", __func__);
7170
_set_timer(&padapter->cfg80211_wdinfo.remain_on_ch_timer, pwdinfo->ext_listen_period);
7171
}
7172
#endif /* CONFIG_CONCURRENT_MODE */
7173
}
7174
#endif /* CONFIG_P2P */
7175
7176
#ifdef CONFIG_MCC_MODE
7177
if (MCC_EN(padapter)) {
7178
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
7179
/* don't set channel, issue frame directly */
7180
goto issue_mgmt_frame;
7181
}
7182
#endif /* CONFIG_MCC_MODE */
7183
7184
if (rtw_mi_check_status(padapter, MI_LINKED)
7185
&& tx_ch != u_ch
7186
) {
7187
rtw_leave_opch(padapter);
7188
leave_op = 1;
7189
7190
#if defined(RTW_ROCH_BACK_OP) && defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
7191
if (rtw_cfg80211_get_is_roch(padapter)
7192
&& ATOMIC_READ(&pwdev_priv->switch_ch_to) == 1
7193
) {
7194
u16 ext_listen_period;
7195
7196
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED))
7197
ext_listen_period = 500;
7198
else
7199
ext_listen_period = pwdinfo->ext_listen_period;
7200
ATOMIC_SET(&pwdev_priv->switch_ch_to, 0);
7201
_set_timer(&pwdinfo->ap_p2p_switch_timer, ext_listen_period);
7202
RTW_INFO("%s, set switch ch timer, period=%d\n", __func__, ext_listen_period);
7203
}
7204
#endif /* RTW_ROCH_BACK_OP && CONFIG_P2P && CONFIG_CONCURRENT_MODE */
7205
}
7206
7207
if (tx_ch != rtw_get_oper_ch(padapter))
7208
set_channel_bwmode(padapter, tx_ch, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
7209
#ifdef CONFIG_MCC_MODE
7210
issue_mgmt_frame:
7211
#endif
7212
/* starting alloc mgmt frame to dump it */
7213
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7214
if (pmgntframe == NULL) {
7215
/* ret = -ENOMEM; */
7216
ret = _FAIL;
7217
goto exit;
7218
}
7219
7220
/* update attribute */
7221
pattrib = &pmgntframe->attrib;
7222
update_mgntframe_attrib(padapter, pattrib);
7223
7224
if (no_cck && IS_CCK_RATE(pattrib->rate)) {
7225
/* force OFDM 6M rate*/
7226
pattrib->rate = MGN_6M;
7227
pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
7228
}
7229
7230
pattrib->retry_ctrl = _FALSE;
7231
7232
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7233
7234
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7235
7236
_rtw_memcpy(pframe, (void *)buf, len);
7237
pattrib->pktlen = len;
7238
7239
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7240
/* update seq number */
7241
pmlmeext->mgnt_seq = GetSequence(pwlanhdr);
7242
pattrib->seqnum = pmlmeext->mgnt_seq;
7243
pmlmeext->mgnt_seq++;
7244
7245
#ifdef CONFIG_P2P
7246
rtw_xframe_chk_wfd_ie(pmgntframe);
7247
#endif /* CONFIG_P2P */
7248
7249
pattrib->last_txcmdsz = pattrib->pktlen;
7250
7251
if (wait_ack) {
7252
if (dump_mgntframe_and_wait_ack(padapter, pmgntframe) != _SUCCESS) {
7253
ack = _FALSE;
7254
ret = _FAIL;
7255
7256
#ifdef CONFIG_DEBUG_CFG80211
7257
RTW_INFO("%s, ack == _FAIL\n", __func__);
7258
#endif
7259
} else {
7260
7261
#ifdef CONFIG_XMIT_ACK
7262
if (!MLME_IS_MESH(padapter)) /* TODO: remove this sleep for all mode */
7263
rtw_msleep_os(50);
7264
#endif
7265
#ifdef CONFIG_DEBUG_CFG80211
7266
RTW_INFO("%s, ack=%d, ok!\n", __func__, ack);
7267
#endif
7268
ret = _SUCCESS;
7269
}
7270
} else {
7271
dump_mgntframe(padapter, pmgntframe);
7272
ret = _SUCCESS;
7273
}
7274
7275
exit:
7276
#ifdef CONFIG_P2P
7277
if (rtw_cfg80211_get_is_roch(padapter)
7278
&& !roch_stay_in_cur_chan(padapter)
7279
&& pcfg80211_wdinfo->remain_on_ch_channel.hw_value != u_ch
7280
) {
7281
/* roch is ongoing, switch back to rch */
7282
if (pcfg80211_wdinfo->remain_on_ch_channel.hw_value != tx_ch)
7283
set_channel_bwmode(padapter, pcfg80211_wdinfo->remain_on_ch_channel.hw_value
7284
, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
7285
} else
7286
#endif
7287
if (leave_op) {
7288
if (rtw_mi_check_status(padapter, MI_LINKED)) {
7289
u8 u_bw = rtw_mi_get_union_bw(padapter);
7290
u8 u_offset = rtw_mi_get_union_offset(padapter);
7291
7292
set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
7293
}
7294
rtw_back_opch(padapter);
7295
}
7296
7297
rtw_cfg80211_set_is_mgmt_tx(padapter, 0);
7298
7299
#ifdef CONFIG_BT_COEXIST
7300
rtw_btcoex_ScanNotify(padapter, _FALSE);
7301
#endif
7302
7303
#ifdef CONFIG_DEBUG_CFG80211
7304
RTW_INFO("%s, ret=%d\n", __func__, ret);
7305
#endif
7306
7307
return ret;
7308
7309
}
7310
7311
u8 rtw_mgnt_tx_handler(_adapter *adapter, u8 *buf)
7312
{
7313
u8 rst = H2C_CMD_FAIL;
7314
struct mgnt_tx_parm *mgnt_parm = (struct mgnt_tx_parm *)buf;
7315
7316
if (_cfg80211_rtw_mgmt_tx(adapter, mgnt_parm->tx_ch, mgnt_parm->no_cck,
7317
mgnt_parm->buf, mgnt_parm->len, mgnt_parm->wait_ack) == _SUCCESS)
7318
rst = H2C_SUCCESS;
7319
7320
return rst;
7321
}
7322
7323
static int cfg80211_rtw_mgmt_tx(struct wiphy *wiphy,
7324
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7325
struct wireless_dev *wdev,
7326
#else
7327
struct net_device *ndev,
7328
#endif
7329
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE)
7330
struct ieee80211_channel *chan,
7331
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
7332
bool offchan,
7333
#endif
7334
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7335
enum nl80211_channel_type channel_type,
7336
#endif
7337
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7338
bool channel_type_valid,
7339
#endif
7340
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
7341
unsigned int wait,
7342
#endif
7343
const u8 *buf, size_t len,
7344
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
7345
bool no_cck,
7346
#endif
7347
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
7348
bool dont_wait_for_ack,
7349
#endif
7350
#else
7351
struct cfg80211_mgmt_tx_params *params,
7352
#endif
7353
u64 *cookie)
7354
{
7355
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(COMPAT_KERNEL_RELEASE)
7356
struct ieee80211_channel *chan = params->chan;
7357
const u8 *buf = params->buf;
7358
size_t len = params->len;
7359
bool no_cck = params->no_cck;
7360
#endif
7361
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
7362
bool no_cck = 0;
7363
#endif
7364
int ret = 0;
7365
u8 tx_ret;
7366
int wait_ack = 1;
7367
const u8 *dump_buf = buf;
7368
size_t dump_len = len;
7369
u32 dump_limit = RTW_MAX_MGMT_TX_CNT;
7370
u32 dump_cnt = 0;
7371
u32 sleep_ms = 0;
7372
u32 retry_guarantee_ms = 0;
7373
bool ack = _TRUE;
7374
u8 tx_ch;
7375
u8 category, action;
7376
u8 frame_styp;
7377
#ifdef CONFIG_P2P
7378
u8 is_p2p = 0;
7379
#endif
7380
int type = (-1);
7381
systime start = rtw_get_current_time();
7382
_adapter *padapter;
7383
struct dvobj_priv *dvobj;
7384
struct rtw_wdev_priv *pwdev_priv;
7385
struct rf_ctl_t *rfctl;
7386
7387
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7388
#if defined(RTW_DEDICATED_P2P_DEVICE)
7389
if (wdev == wiphy_to_pd_wdev(wiphy))
7390
padapter = wiphy_to_adapter(wiphy);
7391
else
7392
#endif
7393
if (wdev_to_ndev(wdev))
7394
padapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
7395
else {
7396
ret = -EINVAL;
7397
goto exit;
7398
}
7399
#else
7400
struct wireless_dev *wdev;
7401
7402
if (ndev == NULL) {
7403
ret = -EINVAL;
7404
goto exit;
7405
}
7406
padapter = (_adapter *)rtw_netdev_priv(ndev);
7407
wdev = ndev_to_wdev(ndev);
7408
#endif
7409
7410
if (chan == NULL) {
7411
ret = -EINVAL;
7412
goto exit;
7413
}
7414
7415
rfctl = adapter_to_rfctl(padapter);
7416
tx_ch = (u8)ieee80211_frequency_to_channel(chan->center_freq);
7417
if (IS_CH_WAITING(rfctl)) {
7418
#ifdef CONFIG_DFS_MASTER
7419
if (_rtw_rfctl_overlap_radar_detect_ch(rfctl, tx_ch, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE)) {
7420
ret = -EINVAL;
7421
goto exit;
7422
}
7423
#endif
7424
}
7425
7426
dvobj = adapter_to_dvobj(padapter);
7427
pwdev_priv = adapter_wdev_data(padapter);
7428
7429
/* cookie generation */
7430
*cookie = pwdev_priv->mgmt_tx_cookie++;
7431
7432
#ifdef CONFIG_DEBUG_CFG80211
7433
RTW_INFO(FUNC_ADPT_FMT"%s len=%zu, ch=%d"
7434
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7435
", ch_type=%d"
7436
#endif
7437
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7438
", channel_type_valid=%d"
7439
#endif
7440
"\n", FUNC_ADPT_ARG(padapter), wdev == wiphy_to_pd_wdev(wiphy) ? " PD" : ""
7441
, len, tx_ch
7442
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7443
, channel_type
7444
#endif
7445
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)) && (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0))
7446
, channel_type_valid
7447
#endif
7448
);
7449
#endif /* CONFIG_DEBUG_CFG80211 */
7450
7451
/* indicate ack before issue frame to avoid racing with rsp frame */
7452
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
7453
rtw_cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack, GFP_KERNEL);
7454
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 36))
7455
cfg80211_action_tx_status(ndev, *cookie, buf, len, ack, GFP_KERNEL);
7456
#endif
7457
7458
frame_styp = le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl) & IEEE80211_FCTL_STYPE;
7459
if (IEEE80211_STYPE_PROBE_RESP == frame_styp) {
7460
#ifdef CONFIG_DEBUG_CFG80211
7461
RTW_INFO("RTW_Tx: probe_resp tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
7462
#endif /* CONFIG_DEBUG_CFG80211 */
7463
wait_ack = 0;
7464
goto dump;
7465
}
7466
else if (frame_styp == RTW_IEEE80211_STYPE_AUTH) {
7467
int retval = 0;
7468
7469
RTW_INFO("RTW_Tx:tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
7470
7471
retval = rtw_sae_preprocess(padapter, buf, len, _TRUE);
7472
if (retval == 2)
7473
goto exit;
7474
if (retval == 0)
7475
RTW_INFO("RTW_Tx:AUTH\n");
7476
dump_limit = 1;
7477
goto dump;
7478
}
7479
7480
if (rtw_action_frame_parse(buf, len, &category, &action) == _FALSE) {
7481
RTW_INFO(FUNC_ADPT_FMT" frame_control:0x%02x\n", FUNC_ADPT_ARG(padapter),
7482
le16_to_cpu(((struct rtw_ieee80211_hdr_3addr *)buf)->frame_ctl));
7483
goto exit;
7484
}
7485
7486
RTW_INFO("RTW_Tx:tx_ch=%d, no_cck=%u, da="MAC_FMT"\n", tx_ch, no_cck, MAC_ARG(GetAddr1Ptr(buf)));
7487
#ifdef CONFIG_P2P
7488
type = rtw_p2p_check_frames(padapter, buf, len, _TRUE);
7489
if (type >= 0) {
7490
is_p2p = 1;
7491
no_cck = 1; /* force no CCK for P2P frames */
7492
goto dump;
7493
}
7494
#endif
7495
#ifdef CONFIG_RTW_MESH
7496
if (MLME_IS_MESH(padapter)) {
7497
type = rtw_mesh_check_frames_tx(padapter, &dump_buf, &dump_len);
7498
if (type >= 0) {
7499
dump_limit = 1;
7500
goto dump;
7501
}
7502
}
7503
#endif
7504
if (category == RTW_WLAN_CATEGORY_PUBLIC) {
7505
RTW_INFO("RTW_Tx:%s\n", action_public_str(action));
7506
switch (action) {
7507
case ACT_PUBLIC_GAS_INITIAL_REQ:
7508
case ACT_PUBLIC_GAS_INITIAL_RSP:
7509
sleep_ms = 50;
7510
retry_guarantee_ms = RTW_MAX_MGMT_TX_MS_GAS;
7511
break;
7512
}
7513
}
7514
#ifdef CONFIG_RTW_80211K
7515
else if (category == RTW_WLAN_CATEGORY_RADIO_MEAS)
7516
RTW_INFO("RTW_Tx: RRM Action\n");
7517
#endif
7518
else
7519
RTW_INFO("RTW_Tx:category(%u), action(%u)\n", category, action);
7520
7521
dump:
7522
7523
rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
7524
if (_FAIL == rtw_pwr_wakeup(padapter)) {
7525
ret = -EFAULT;
7526
goto cancel_ps_deny;
7527
}
7528
7529
while (1) {
7530
dump_cnt++;
7531
7532
rtw_mi_set_scan_deny(padapter, 1000);
7533
rtw_mi_scan_abort(padapter, _TRUE);
7534
tx_ret = rtw_mgnt_tx_cmd(padapter, tx_ch, no_cck, dump_buf, dump_len, wait_ack, RTW_CMDF_WAIT_ACK);
7535
if (tx_ret == _SUCCESS
7536
|| (dump_cnt >= dump_limit && rtw_get_passing_time_ms(start) >= retry_guarantee_ms))
7537
break;
7538
7539
if (sleep_ms > 0)
7540
rtw_msleep_os(sleep_ms);
7541
}
7542
7543
if (tx_ret != _SUCCESS || dump_cnt > 1) {
7544
RTW_INFO(FUNC_ADPT_FMT" %s (%d/%d) in %d ms\n", FUNC_ADPT_ARG(padapter),
7545
tx_ret == _SUCCESS ? "OK" : "FAIL", dump_cnt, dump_limit, rtw_get_passing_time_ms(start));
7546
}
7547
7548
#ifdef CONFIG_P2P
7549
if (is_p2p) {
7550
switch (type) {
7551
case P2P_GO_NEGO_CONF:
7552
if (0) {
7553
RTW_INFO(FUNC_ADPT_FMT" Nego confirm. state=%u, status=%u, iaddr="MAC_FMT"\n"
7554
, FUNC_ADPT_ARG(padapter), pwdev_priv->nego_info.state, pwdev_priv->nego_info.status
7555
, MAC_ARG(pwdev_priv->nego_info.iface_addr));
7556
}
7557
if (pwdev_priv->nego_info.state == 2
7558
&& pwdev_priv->nego_info.status == 0
7559
&& rtw_check_invalid_mac_address(pwdev_priv->nego_info.iface_addr, _FALSE) == _FALSE
7560
) {
7561
_adapter *intended_iface = dvobj_get_adapter_by_addr(dvobj, pwdev_priv->nego_info.iface_addr);
7562
7563
if (intended_iface) {
7564
RTW_INFO(FUNC_ADPT_FMT" Nego confirm. Allow only "ADPT_FMT" to scan for 2000 ms\n"
7565
, FUNC_ADPT_ARG(padapter), ADPT_ARG(intended_iface));
7566
/* allow only intended_iface to do scan for 2000 ms */
7567
rtw_mi_set_scan_deny(padapter, 2000);
7568
rtw_clear_scan_deny(intended_iface);
7569
}
7570
}
7571
break;
7572
case P2P_INVIT_RESP:
7573
if (pwdev_priv->invit_info.flags & BIT(0)
7574
&& pwdev_priv->invit_info.status == 0
7575
) {
7576
rtw_clear_scan_deny(padapter);
7577
RTW_INFO(FUNC_ADPT_FMT" agree with invitation of persistent group\n",
7578
FUNC_ADPT_ARG(padapter));
7579
#if !RTW_P2P_GROUP_INTERFACE
7580
rtw_mi_buddy_set_scan_deny(padapter, 5000);
7581
#endif
7582
rtw_pwr_wakeup_ex(padapter, 5000);
7583
}
7584
break;
7585
}
7586
}
7587
#endif /* CONFIG_P2P */
7588
7589
cancel_ps_deny:
7590
rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
7591
7592
if (dump_buf != buf)
7593
rtw_mfree((u8 *)dump_buf, dump_len);
7594
exit:
7595
return ret;
7596
}
7597
7598
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0))
7599
static void cfg80211_rtw_update_mgmt_frame_register(struct wiphy *wiphy,
7600
struct wireless_dev *wdev,
7601
struct mgmt_frame_regs *upd)
7602
#else
7603
static void cfg80211_rtw_mgmt_frame_register(struct wiphy *wiphy,
7604
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7605
struct wireless_dev *wdev,
7606
#else
7607
struct net_device *ndev,
7608
#endif
7609
u16 frame_type, bool reg)
7610
#endif
7611
{
7612
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7613
struct net_device *ndev = wdev_to_ndev(wdev);
7614
#endif
7615
_adapter *adapter;
7616
7617
struct rtw_wdev_priv *pwdev_priv;
7618
7619
if (ndev == NULL)
7620
goto exit;
7621
7622
adapter = (_adapter *)rtw_netdev_priv(ndev);
7623
pwdev_priv = adapter_wdev_data(adapter);
7624
7625
#ifdef CONFIG_DEBUG_CFG80211
7626
RTW_INFO(FUNC_ADPT_FMT" frame_type:%x, reg:%d\n", FUNC_ADPT_ARG(adapter),
7627
frame_type, reg);
7628
#endif
7629
7630
exit:
7631
return;
7632
}
7633
7634
#if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
7635
static int cfg80211_rtw_tdls_mgmt(struct wiphy *wiphy,
7636
struct net_device *ndev,
7637
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
7638
const u8 *peer,
7639
#else
7640
u8 *peer,
7641
#endif
7642
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 5, 0))
7643
int link_id,
7644
#endif
7645
u8 action_code,
7646
u8 dialog_token,
7647
u16 status_code,
7648
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0))
7649
u32 peer_capability,
7650
#endif
7651
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 17, 0))
7652
bool initiator,
7653
#endif
7654
const u8 *buf,
7655
size_t len)
7656
{
7657
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
7658
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7659
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
7660
int ret = 0;
7661
struct tdls_txmgmt txmgmt;
7662
7663
if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
7664
RTW_INFO("Discard tdls action:%d, since hal doesn't support tdls\n", action_code);
7665
goto discard;
7666
}
7667
7668
if (rtw_is_tdls_enabled(padapter) == _FALSE) {
7669
RTW_INFO("TDLS is not enabled\n");
7670
goto discard;
7671
}
7672
7673
if (rtw_tdls_is_driver_setup(padapter)) {
7674
RTW_INFO("Discard tdls action:%d, let driver to set up direct link\n", action_code);
7675
goto discard;
7676
}
7677
7678
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
7679
_rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
7680
txmgmt.action_code = action_code;
7681
txmgmt.dialog_token = dialog_token;
7682
txmgmt.status_code = status_code;
7683
txmgmt.len = len;
7684
txmgmt.buf = (u8 *)rtw_malloc(txmgmt.len);
7685
if (txmgmt.buf == NULL) {
7686
ret = -ENOMEM;
7687
goto bad;
7688
}
7689
_rtw_memcpy(txmgmt.buf, (void *)buf, txmgmt.len);
7690
7691
/* Debug purpose */
7692
#if 1
7693
RTW_INFO("%s %d\n", __FUNCTION__, __LINE__);
7694
RTW_INFO("peer:"MAC_FMT", action code:%d, dialog:%d, status code:%d\n",
7695
MAC_ARG(txmgmt.peer), txmgmt.action_code,
7696
txmgmt.dialog_token, txmgmt.status_code);
7697
if (txmgmt.len > 0) {
7698
int i = 0;
7699
for (; i < len; i++)
7700
printk("%02x ", *(txmgmt.buf + i));
7701
RTW_INFO("len:%d\n", (u32)txmgmt.len);
7702
}
7703
#endif
7704
7705
switch (txmgmt.action_code) {
7706
case TDLS_SETUP_REQUEST:
7707
issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
7708
break;
7709
case TDLS_SETUP_RESPONSE:
7710
issue_tdls_setup_rsp(padapter, &txmgmt);
7711
break;
7712
case TDLS_SETUP_CONFIRM:
7713
issue_tdls_setup_cfm(padapter, &txmgmt);
7714
break;
7715
case TDLS_TEARDOWN:
7716
issue_tdls_teardown(padapter, &txmgmt, _TRUE);
7717
break;
7718
case TDLS_DISCOVERY_REQUEST:
7719
issue_tdls_dis_req(padapter, &txmgmt);
7720
break;
7721
case TDLS_DISCOVERY_RESPONSE:
7722
issue_tdls_dis_rsp(padapter, &txmgmt, pmlmeinfo->enc_algo ? _TRUE : _FALSE);
7723
break;
7724
}
7725
7726
bad:
7727
if (txmgmt.buf)
7728
rtw_mfree(txmgmt.buf, txmgmt.len);
7729
7730
discard:
7731
return ret;
7732
}
7733
7734
static int cfg80211_rtw_tdls_oper(struct wiphy *wiphy,
7735
struct net_device *ndev,
7736
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
7737
const u8 *peer,
7738
#else
7739
u8 *peer,
7740
#endif
7741
enum nl80211_tdls_operation oper)
7742
{
7743
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
7744
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
7745
struct tdls_txmgmt txmgmt;
7746
struct sta_info *ptdls_sta = NULL;
7747
7748
RTW_INFO(FUNC_NDEV_FMT", nl80211_tdls_operation:%d\n", FUNC_NDEV_ARG(ndev), oper);
7749
7750
if (hal_chk_wl_func(padapter, WL_FUNC_TDLS) == _FALSE) {
7751
RTW_INFO("Discard tdls oper:%d, since hal doesn't support tdls\n", oper);
7752
return 0;
7753
}
7754
7755
if (rtw_is_tdls_enabled(padapter) == _FALSE) {
7756
RTW_INFO("TDLS is not enabled\n");
7757
return 0;
7758
}
7759
7760
#ifdef CONFIG_LPS
7761
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 0);
7762
#endif /* CONFIG_LPS */
7763
7764
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
7765
if (peer)
7766
_rtw_memcpy(txmgmt.peer, peer, ETH_ALEN);
7767
7768
if (rtw_tdls_is_driver_setup(padapter)) {
7769
/* these two cases are done by driver itself */
7770
if (oper == NL80211_TDLS_ENABLE_LINK || oper == NL80211_TDLS_DISABLE_LINK)
7771
return 0;
7772
}
7773
7774
switch (oper) {
7775
case NL80211_TDLS_DISCOVERY_REQ:
7776
issue_tdls_dis_req(padapter, &txmgmt);
7777
break;
7778
case NL80211_TDLS_SETUP:
7779
#ifdef CONFIG_WFD
7780
if (_AES_ != padapter->securitypriv.dot11PrivacyAlgrthm) {
7781
if (padapter->wdinfo.wfd_tdls_weaksec == _TRUE)
7782
issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
7783
else
7784
RTW_INFO("[%s] Current link is not AES, SKIP sending the tdls setup request!!\n", __FUNCTION__);
7785
} else
7786
#endif /* CONFIG_WFD */
7787
{
7788
issue_tdls_setup_req(padapter, &txmgmt, _TRUE);
7789
}
7790
break;
7791
case NL80211_TDLS_TEARDOWN:
7792
ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), txmgmt.peer);
7793
if (ptdls_sta != NULL) {
7794
txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
7795
issue_tdls_teardown(padapter, &txmgmt, _TRUE);
7796
} else
7797
RTW_INFO("TDLS peer not found\n");
7798
break;
7799
case NL80211_TDLS_ENABLE_LINK:
7800
RTW_INFO(FUNC_NDEV_FMT", NL80211_TDLS_ENABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
7801
ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), (u8 *)peer);
7802
if (ptdls_sta != NULL) {
7803
rtw_tdls_set_link_established(padapter, _TRUE);
7804
ptdls_sta->tdls_sta_state |= TDLS_LINKED_STATE;
7805
ptdls_sta->state |= _FW_LINKED;
7806
rtw_tdls_cmd(padapter, txmgmt.peer, TDLS_ESTABLISHED);
7807
}
7808
break;
7809
case NL80211_TDLS_DISABLE_LINK:
7810
RTW_INFO(FUNC_NDEV_FMT", NL80211_TDLS_DISABLE_LINK;mac:"MAC_FMT"\n", FUNC_NDEV_ARG(ndev), MAC_ARG(peer));
7811
ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), (u8 *)peer);
7812
if (ptdls_sta != NULL) {
7813
rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
7814
rtw_tdls_cmd(padapter, (u8 *)peer, TDLS_TEARDOWN_STA_LOCALLY_POST);
7815
}
7816
break;
7817
}
7818
return 0;
7819
}
7820
#endif /* CONFIG_TDLS */
7821
7822
#if defined(CONFIG_RTW_MESH) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
7823
7824
#if DBG_RTW_CFG80211_MESH_CONF
7825
#define LEGACY_RATES_STR_LEN (RTW_G_RATES_NUM * 5 + 1)
7826
int get_legacy_rates_str(struct wiphy *wiphy, enum nl80211_band band, u32 mask, char *buf)
7827
{
7828
int i;
7829
int cnt = 0;
7830
7831
for (i = 0; i < wiphy->bands[band]->n_bitrates; i++) {
7832
if (mask & BIT(i)) {
7833
cnt += snprintf(buf + cnt, LEGACY_RATES_STR_LEN - cnt -1, "%d.%d "
7834
, wiphy->bands[band]->bitrates[i].bitrate / 10
7835
, wiphy->bands[band]->bitrates[i].bitrate % 10);
7836
if (cnt >= LEGACY_RATES_STR_LEN - 1)
7837
break;
7838
}
7839
}
7840
7841
return cnt;
7842
}
7843
7844
void dump_mesh_setup(void *sel, struct wiphy *wiphy, const struct mesh_setup *setup)
7845
{
7846
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7847
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
7848
struct cfg80211_chan_def *chdef = (struct cfg80211_chan_def *)(&setup->chandef);
7849
#endif
7850
struct ieee80211_channel *chan;
7851
#endif
7852
7853
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
7854
chan = (struct ieee80211_channel *)chdef->chan;
7855
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7856
chan = (struct ieee80211_channel *)setup->channel;
7857
#endif
7858
7859
RTW_PRINT_SEL(sel, "mesh_id:\"%s\", len:%u\n", setup->mesh_id, setup->mesh_id_len);
7860
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
7861
RTW_PRINT_SEL(sel, "sync_method:%u\n", setup->sync_method);
7862
#endif
7863
RTW_PRINT_SEL(sel, "path_sel_proto:%u, path_metric:%u\n", setup->path_sel_proto, setup->path_metric);
7864
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7865
RTW_PRINT_SEL(sel, "auth_id:%u\n", setup->auth_id);
7866
#endif
7867
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
7868
if (setup->ie && setup->ie_len) {
7869
RTW_PRINT_SEL(sel, "ie:%p, len:%u\n", setup->ie, setup->ie_len);
7870
dump_ies(RTW_DBGDUMP, setup->ie, setup->ie_len);
7871
}
7872
#else
7873
if (setup->vendor_ie && setup->vendor_ie_len) {
7874
RTW_PRINT_SEL(sel, "ie:%p, len:%u\n", setup->vendor_ie, setup->vendor_ie_len);
7875
dump_ies(RTW_DBGDUMP, setup->vendor_ie, setup->vendor_ie_len);
7876
}
7877
#endif
7878
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
7879
RTW_PRINT_SEL(sel, "is_authenticated:%d, is_secure:%d\n", setup->is_authenticated, setup->is_secure);
7880
#endif
7881
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
7882
RTW_PRINT_SEL(sel, "user_mpm:%d\n", setup->user_mpm);
7883
#endif
7884
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
7885
RTW_PRINT_SEL(sel, "dtim_period:%u, beacon_interval:%u\n", setup->dtim_period, setup->beacon_interval);
7886
#endif
7887
7888
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7889
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
7890
RTW_PRINT_SEL(sel, "center_freq:%u, ch:%u, width:%s, cfreq1:%u, cfreq2:%u\n"
7891
, chan->center_freq, chan->hw_value, nl80211_chan_width_str(chdef->width), chdef->center_freq1, chdef->center_freq2);
7892
#else
7893
RTW_PRINT_SEL(sel, "center_freq:%u, ch:%u, channel_type:%s\n"
7894
, chan->center_freq, chan->hw_value, nl80211_channel_type_str(setup->channel_type));
7895
#endif
7896
#endif
7897
7898
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
7899
if (setup->mcast_rate[chan->band]) {
7900
RTW_PRINT_SEL(sel, "mcast_rate:%d.%d\n"
7901
, wiphy->bands[chan->band]->bitrates[setup->mcast_rate[chan->band] - 1].bitrate / 10
7902
, wiphy->bands[chan->band]->bitrates[setup->mcast_rate[chan->band] - 1].bitrate % 10
7903
);
7904
}
7905
#endif
7906
7907
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
7908
if (setup->basic_rates) {
7909
char buf[LEGACY_RATES_STR_LEN] = {0};
7910
7911
get_legacy_rates_str(wiphy, chan->band, setup->basic_rates, buf);
7912
RTW_PRINT_SEL(sel, "basic_rates:%s\n", buf);
7913
}
7914
#endif
7915
7916
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0))
7917
if (setup->beacon_rate.control[chan->band].legacy) {
7918
char buf[LEGACY_RATES_STR_LEN] = {0};
7919
7920
get_legacy_rates_str(wiphy, chan->band, setup->beacon_rate.control[chan->band].legacy, buf);
7921
RTW_PRINT_SEL(sel, "beacon_rate.legacy:%s\n", buf);
7922
}
7923
if (*((u32 *)&(setup->beacon_rate.control[chan->band].ht_mcs[0]))
7924
|| *((u32 *)&(setup->beacon_rate.control[chan->band].ht_mcs[4]))
7925
|| *((u16 *)&(setup->beacon_rate.control[chan->band].ht_mcs[8]))
7926
) {
7927
RTW_PRINT_SEL(sel, "beacon_rate.ht_mcs:"HT_RX_MCS_BMP_FMT"\n"
7928
, HT_RX_MCS_BMP_ARG(setup->beacon_rate.control[chan->band].ht_mcs));
7929
}
7930
7931
if (setup->beacon_rate.control[chan->band].vht_mcs[0]
7932
|| setup->beacon_rate.control[chan->band].vht_mcs[1]
7933
|| setup->beacon_rate.control[chan->band].vht_mcs[2]
7934
|| setup->beacon_rate.control[chan->band].vht_mcs[3]
7935
) {
7936
int i;
7937
7938
for (i = 0; i < 4; i++) {/* parsing up to 4SS */
7939
u16 mcs_mask = setup->beacon_rate.control[chan->band].vht_mcs[i];
7940
7941
RTW_PRINT_SEL(sel, "beacon_rate.vht_mcs[%d]:%s\n", i
7942
, mcs_mask == 0x00FF ? "0~7" : mcs_mask == 0x01FF ? "0~8" : mcs_mask == 0x03FF ? "0~9" : "invalid");
7943
}
7944
}
7945
7946
if (setup->beacon_rate.control[chan->band].gi) {
7947
RTW_PRINT_SEL(sel, "beacon_rate.gi:%s\n"
7948
, setup->beacon_rate.control[chan->band].gi == NL80211_TXRATE_FORCE_SGI ? "SGI" :
7949
setup->beacon_rate.control[chan->band].gi == NL80211_TXRATE_FORCE_LGI ? "LGI" : "invalid"
7950
);
7951
}
7952
#endif
7953
}
7954
7955
void dump_mesh_config(void *sel, const struct mesh_config *conf)
7956
{
7957
RTW_PRINT_SEL(sel, "dot11MeshRetryTimeout:%u\n", conf->dot11MeshRetryTimeout);
7958
RTW_PRINT_SEL(sel, "dot11MeshConfirmTimeout:%u\n", conf->dot11MeshConfirmTimeout);
7959
RTW_PRINT_SEL(sel, "dot11MeshHoldingTimeout:%u\n", conf->dot11MeshHoldingTimeout);
7960
RTW_PRINT_SEL(sel, "dot11MeshMaxPeerLinks:%u\n", conf->dot11MeshMaxPeerLinks);
7961
RTW_PRINT_SEL(sel, "dot11MeshMaxRetries:%u\n", conf->dot11MeshMaxRetries);
7962
RTW_PRINT_SEL(sel, "dot11MeshTTL:%u\n", conf->dot11MeshTTL);
7963
RTW_PRINT_SEL(sel, "element_ttl:%u\n", conf->element_ttl);
7964
RTW_PRINT_SEL(sel, "auto_open_plinks:%d\n", conf->auto_open_plinks);
7965
7966
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
7967
RTW_PRINT_SEL(sel, "dot11MeshNbrOffsetMaxNeighbor:%u\n", conf->dot11MeshNbrOffsetMaxNeighbor);
7968
#endif
7969
7970
RTW_PRINT_SEL(sel, "dot11MeshHWMPmaxPREQretries:%u\n", conf->dot11MeshHWMPmaxPREQretries);
7971
RTW_PRINT_SEL(sel, "path_refresh_time:%u\n", conf->path_refresh_time);
7972
RTW_PRINT_SEL(sel, "min_discovery_timeout:%u\n", conf->min_discovery_timeout);
7973
RTW_PRINT_SEL(sel, "dot11MeshHWMPactivePathTimeout:%u\n", conf->dot11MeshHWMPactivePathTimeout);
7974
RTW_PRINT_SEL(sel, "dot11MeshHWMPpreqMinInterval:%u\n", conf->dot11MeshHWMPpreqMinInterval);
7975
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
7976
RTW_PRINT_SEL(sel, "dot11MeshHWMPperrMinInterval:%u\n", conf->dot11MeshHWMPperrMinInterval);
7977
#endif
7978
RTW_PRINT_SEL(sel, "dot11MeshHWMPnetDiameterTraversalTime:%u\n", conf->dot11MeshHWMPnetDiameterTraversalTime);
7979
RTW_PRINT_SEL(sel, "dot11MeshHWMPRootMode:%u\n", conf->dot11MeshHWMPRootMode);
7980
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
7981
RTW_PRINT_SEL(sel, "dot11MeshHWMPRannInterval:%u\n", conf->dot11MeshHWMPRannInterval);
7982
RTW_PRINT_SEL(sel, "dot11MeshGateAnnouncementProtocol:%d\n", conf->dot11MeshGateAnnouncementProtocol);
7983
#endif
7984
7985
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
7986
RTW_PRINT_SEL(sel, "dot11MeshForwarding:%d\n", conf->dot11MeshForwarding);
7987
RTW_PRINT_SEL(sel, "rssi_threshold:%d\n", conf->rssi_threshold);
7988
#endif
7989
7990
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
7991
RTW_PRINT_SEL(sel, "ht_opmode:0x%04x\n", conf->ht_opmode);
7992
#endif
7993
7994
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
7995
RTW_PRINT_SEL(sel, "dot11MeshHWMPactivePathToRootTimeout:%u\n", conf->dot11MeshHWMPactivePathToRootTimeout);
7996
RTW_PRINT_SEL(sel, "dot11MeshHWMProotInterval:%u\n", conf->dot11MeshHWMProotInterval);
7997
RTW_PRINT_SEL(sel, "dot11MeshHWMPconfirmationInterval:%u\n", conf->dot11MeshHWMPconfirmationInterval);
7998
#endif
7999
8000
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
8001
RTW_PRINT_SEL(sel, "power_mode:%s\n", nl80211_mesh_power_mode_str(conf->power_mode));
8002
RTW_PRINT_SEL(sel, "dot11MeshAwakeWindowDuration:%u\n", conf->dot11MeshAwakeWindowDuration);
8003
#endif
8004
8005
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8006
RTW_PRINT_SEL(sel, "plink_timeout:%u\n", conf->plink_timeout);
8007
#endif
8008
}
8009
#endif /* DBG_RTW_CFG80211_MESH_CONF */
8010
8011
static void rtw_cfg80211_mesh_info_set_profile(struct rtw_mesh_info *minfo, const struct mesh_setup *setup)
8012
{
8013
_rtw_memcpy(minfo->mesh_id, setup->mesh_id, setup->mesh_id_len);
8014
minfo->mesh_id_len = setup->mesh_id_len;
8015
minfo->mesh_pp_id = setup->path_sel_proto;
8016
minfo->mesh_pm_id = setup->path_metric;
8017
minfo->mesh_cc_id = 0;
8018
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8019
minfo->mesh_sp_id = setup->sync_method;
8020
#endif
8021
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8022
minfo->mesh_auth_id = setup->auth_id;
8023
#else
8024
if (setup->is_authenticated) {
8025
u8 *rsn_ie;
8026
sint rsn_ie_len;
8027
struct rsne_info info;
8028
u8 *akm;
8029
u8 AKM_SUITE_SAE[4] = {0x00, 0x0F, 0xAC, 0x08};
8030
8031
rsn_ie = rtw_get_ie(setup->ie, WLAN_EID_RSN, &rsn_ie_len, setup->ie_len);
8032
if (!rsn_ie || !rsn_ie_len) {
8033
rtw_warn_on(1);
8034
return;
8035
}
8036
8037
if (rtw_rsne_info_parse(rsn_ie, rsn_ie_len + 2, &info) != _SUCCESS) {
8038
rtw_warn_on(1);
8039
return;
8040
}
8041
8042
if (!info.akm_list || !info.akm_cnt) {
8043
rtw_warn_on(1);
8044
return;
8045
}
8046
8047
akm = info.akm_list;
8048
while (akm < info.akm_list + info.akm_cnt * 4) {
8049
if (_rtw_memcmp(akm, AKM_SUITE_SAE, 4) == _TRUE) {
8050
minfo->mesh_auth_id = 0x01;
8051
break;
8052
}
8053
}
8054
8055
if (!minfo->mesh_auth_id) {
8056
rtw_warn_on(1);
8057
return;
8058
}
8059
}
8060
#endif
8061
}
8062
8063
static inline bool chk_mesh_attr(enum nl80211_meshconf_params parm, u32 mask)
8064
{
8065
return (mask >> (parm - 1)) & 0x1;
8066
}
8067
8068
static void rtw_cfg80211_mesh_cfg_set(_adapter *adapter, const struct mesh_config *conf, u32 mask)
8069
{
8070
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
8071
8072
#if 0 /* driver MPM */
8073
if (chk_mesh_attr(NL80211_MESHCONF_RETRY_TIMEOUT, mask));
8074
if (chk_mesh_attr(NL80211_MESHCONF_CONFIRM_TIMEOUT, mask));
8075
if (chk_mesh_attr(NL80211_MESHCONF_HOLDING_TIMEOUT, mask));
8076
if (chk_mesh_attr(NL80211_MESHCONF_MAX_PEER_LINKS, mask));
8077
if (chk_mesh_attr(NL80211_MESHCONF_MAX_RETRIES, mask));
8078
#endif
8079
8080
if (chk_mesh_attr(NL80211_MESHCONF_TTL, mask))
8081
mcfg->dot11MeshTTL = conf->dot11MeshTTL;
8082
if (chk_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask))
8083
mcfg->element_ttl = conf->element_ttl;
8084
8085
#if 0 /* driver MPM */
8086
if (chk_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask));
8087
#endif
8088
8089
#if 0 /* TBD: synchronization */
8090
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8091
if (chk_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask));
8092
#endif
8093
#endif
8094
8095
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_MAX_PREQ_RETRIES, mask))
8096
mcfg->dot11MeshHWMPmaxPREQretries = conf->dot11MeshHWMPmaxPREQretries;
8097
if (chk_mesh_attr(NL80211_MESHCONF_PATH_REFRESH_TIME, mask))
8098
mcfg->path_refresh_time = conf->path_refresh_time;
8099
if (chk_mesh_attr(NL80211_MESHCONF_MIN_DISCOVERY_TIMEOUT, mask))
8100
mcfg->min_discovery_timeout = conf->min_discovery_timeout;
8101
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_ACTIVE_PATH_TIMEOUT, mask))
8102
mcfg->dot11MeshHWMPactivePathTimeout = conf->dot11MeshHWMPactivePathTimeout;
8103
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_PREQ_MIN_INTERVAL, mask))
8104
mcfg->dot11MeshHWMPpreqMinInterval = conf->dot11MeshHWMPpreqMinInterval;
8105
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
8106
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_PERR_MIN_INTERVAL, mask))
8107
mcfg->dot11MeshHWMPperrMinInterval = conf->dot11MeshHWMPperrMinInterval;
8108
#endif
8109
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_NET_DIAM_TRVS_TIME, mask))
8110
mcfg->dot11MeshHWMPnetDiameterTraversalTime = conf->dot11MeshHWMPnetDiameterTraversalTime;
8111
8112
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_ROOTMODE, mask))
8113
mcfg->dot11MeshHWMPRootMode = conf->dot11MeshHWMPRootMode;
8114
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
8115
if (chk_mesh_attr(NL80211_MESHCONF_GATE_ANNOUNCEMENTS, mask))
8116
mcfg->dot11MeshGateAnnouncementProtocol = conf->dot11MeshGateAnnouncementProtocol;
8117
/* our current gate annc implementation rides on root annc with gate annc bit in PREQ flags */
8118
if (mcfg->dot11MeshGateAnnouncementProtocol
8119
&& mcfg->dot11MeshHWMPRootMode <= RTW_IEEE80211_ROOTMODE_ROOT
8120
) {
8121
mcfg->dot11MeshHWMPRootMode = RTW_IEEE80211_PROACTIVE_RANN;
8122
RTW_INFO(ADPT_FMT" enable PROACTIVE_RANN becaue gate annc is needed\n", ADPT_ARG(adapter));
8123
}
8124
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask))
8125
mcfg->dot11MeshHWMPRannInterval = conf->dot11MeshHWMPRannInterval;
8126
#endif
8127
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
8128
if (chk_mesh_attr(NL80211_MESHCONF_FORWARDING, mask))
8129
mcfg->dot11MeshForwarding = conf->dot11MeshForwarding;
8130
8131
if (chk_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask))
8132
mcfg->rssi_threshold = conf->rssi_threshold;
8133
#endif
8134
8135
#if 0 /* controlled by driver */
8136
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8137
if (chk_mesh_attr(NL80211_MESHCONF_HT_OPMODE, mask));
8138
#endif
8139
#endif
8140
8141
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8142
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask))
8143
mcfg->dot11MeshHWMPactivePathToRootTimeout = conf->dot11MeshHWMPactivePathToRootTimeout;
8144
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask))
8145
mcfg->dot11MeshHWMProotInterval = conf->dot11MeshHWMProotInterval;
8146
if (chk_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask))
8147
mcfg->dot11MeshHWMPconfirmationInterval = conf->dot11MeshHWMPconfirmationInterval;
8148
#endif
8149
8150
#if 0 /* TBD */
8151
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
8152
if (chk_mesh_attr(NL80211_MESHCONF_POWER_MODE, mask));
8153
if (chk_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask));
8154
#endif
8155
#endif
8156
8157
#if 0 /* driver MPM */
8158
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8159
if (chk_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask));
8160
#endif
8161
#endif
8162
}
8163
8164
u8 *rtw_cfg80211_construct_mesh_beacon_ies(struct wiphy *wiphy, _adapter *adapter
8165
, const struct mesh_config *conf, const struct mesh_setup *setup
8166
, uint *ies_len)
8167
{
8168
struct rtw_mesh_info *minfo = &adapter->mesh_info;
8169
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
8170
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8171
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
8172
struct cfg80211_chan_def *chdef = (struct cfg80211_chan_def *)(&setup->chandef);
8173
#endif
8174
struct ieee80211_channel *chan;
8175
u8 ch, bw, offset;
8176
#endif
8177
uint len;
8178
u8 n_bitrates;
8179
u8 ht = 0;
8180
u8 vht = 0;
8181
u8 *rsn_ie = NULL;
8182
sint rsn_ie_len = 0;
8183
u8 *ies = NULL, *c;
8184
u8 supported_rates[RTW_G_RATES_NUM] = {0};
8185
int i;
8186
8187
*ies_len = 0;
8188
8189
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
8190
chan = (struct ieee80211_channel *)chdef->chan;
8191
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8192
chan = (struct ieee80211_channel *)setup->channel;
8193
#endif
8194
8195
n_bitrates = wiphy->bands[chan->band]->n_bitrates;
8196
8197
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8198
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 8, 0))
8199
rtw_get_chbw_from_cfg80211_chan_def(chdef, &ht, &ch, &bw, &offset);
8200
#else
8201
rtw_get_chbw_from_nl80211_channel_type(chan, setup->channel_type, &ht, &ch, &bw, &offset);
8202
#endif
8203
if (!ch)
8204
goto exit;
8205
8206
#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8207
vht = ht && ch > 14 && bw >= CHANNEL_WIDTH_80; /* VHT40/VHT20? */
8208
#endif
8209
8210
RTW_INFO(FUNC_ADPT_FMT" => ch:%u,%u,%u, ht:%u, vht:%u\n"
8211
, FUNC_ADPT_ARG(adapter), ch, bw, offset, ht, vht);
8212
#endif
8213
8214
rsn_ie = rtw_get_ie(setup->ie, WLAN_EID_RSN, &rsn_ie_len, setup->ie_len);
8215
if (rsn_ie && !rsn_ie_len) {
8216
rtw_warn_on(1);
8217
rsn_ie = NULL;
8218
}
8219
8220
len = _BEACON_IE_OFFSET_
8221
+ 2 /* 0-length SSID */
8222
+ (n_bitrates >= 8 ? 8 : n_bitrates) + 2 /* Supported Rates */
8223
+ 3 /* DS parameter set */
8224
+ 6 /* TIM */
8225
+ (n_bitrates > 8 ? n_bitrates - 8 + 2 : 0) /* Extended Supported Rates */
8226
+ (rsn_ie ? rsn_ie_len + 2 : 0) /* RSN */
8227
#if defined(CONFIG_80211N_HT)
8228
+ (ht ? HT_CAP_IE_LEN + 2 + HT_OP_IE_LEN + 2 : 0) /* HT */
8229
#endif
8230
#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8231
+ (vht ? VHT_CAP_IE_LEN + 2 + VHT_OP_IE_LEN + 2 : 0) /* VHT */
8232
#endif
8233
+ minfo->mesh_id_len + 2 /* Mesh ID */
8234
+ 9 /* Mesh configuration */
8235
;
8236
8237
ies = rtw_zmalloc(len);
8238
if (!ies)
8239
goto exit;
8240
8241
/* timestamp */
8242
c = ies + 8;
8243
8244
/* beacon interval */
8245
RTW_PUT_LE16(c , setup->beacon_interval);
8246
c += 2;
8247
8248
/* capability */
8249
if (rsn_ie)
8250
*((u16 *)c) |= cpu_to_le16(cap_Privacy);
8251
c += 2;
8252
8253
/* SSID */
8254
c = rtw_set_ie(c, WLAN_EID_SSID, 0, NULL, NULL);
8255
8256
/* Supported Rates */
8257
for (i = 0; i < n_bitrates; i++) {
8258
supported_rates[i] = wiphy->bands[chan->band]->bitrates[i].bitrate / 5;
8259
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8260
if (setup->basic_rates & BIT(i))
8261
#else
8262
if (rtw_is_basic_rate_mix(supported_rates[i]))
8263
#endif
8264
supported_rates[i] |= IEEE80211_BASIC_RATE_MASK;
8265
}
8266
c = rtw_set_ie(c, WLAN_EID_SUPP_RATES, (n_bitrates >= 8 ? 8 : n_bitrates), supported_rates, NULL);
8267
8268
/* DS parameter set */
8269
c = rtw_set_ie(c, WLAN_EID_DS_PARAMS, 1, &ch, NULL);
8270
8271
/* TIM */
8272
*c = WLAN_EID_TIM;
8273
*(c + 1) = 4;
8274
c += 6;
8275
//c = rtw_set_ie(c, _TIM_IE_, 4, NULL, NULL);
8276
8277
/* Extended Supported Rates */
8278
if (n_bitrates > 8)
8279
c = rtw_set_ie(c, WLAN_EID_EXT_SUPP_RATES, n_bitrates - 8, supported_rates + 8, NULL);
8280
8281
/* RSN */
8282
if (rsn_ie)
8283
c = rtw_set_ie(c, WLAN_EID_RSN, rsn_ie_len, rsn_ie + 2, NULL);
8284
8285
#if defined(CONFIG_80211N_HT)
8286
if (ht) {
8287
struct ieee80211_sta_ht_cap *sta_ht_cap = &wiphy->bands[chan->band]->ht_cap;
8288
u8 ht_cap[HT_CAP_IE_LEN];
8289
u8 ht_op[HT_OP_IE_LEN];
8290
8291
_rtw_memset(ht_cap, 0, HT_CAP_IE_LEN);
8292
_rtw_memset(ht_op, 0, HT_OP_IE_LEN);
8293
8294
/* WLAN_EID_HT_CAP */
8295
RTW_PUT_LE16(HT_CAP_ELE_CAP_INFO(ht_cap), sta_ht_cap->cap);
8296
SET_HT_CAP_ELE_MAX_AMPDU_LEN_EXP(ht_cap, sta_ht_cap->ampdu_factor);
8297
SET_HT_CAP_ELE_MIN_MPDU_S_SPACE(ht_cap, sta_ht_cap->ampdu_density);
8298
_rtw_memcpy(HT_CAP_ELE_SUP_MCS_SET(ht_cap), &sta_ht_cap->mcs, 16);
8299
c = rtw_set_ie(c, WLAN_EID_HT_CAP, HT_CAP_IE_LEN, ht_cap, NULL);
8300
8301
/* WLAN_EID_HT_OPERATION */
8302
SET_HT_OP_ELE_PRI_CHL(ht_op, ch);
8303
switch (offset) {
8304
case HAL_PRIME_CHNL_OFFSET_LOWER:
8305
SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op, SCA);
8306
break;
8307
case HAL_PRIME_CHNL_OFFSET_UPPER:
8308
SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op, SCB);
8309
break;
8310
case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
8311
default:
8312
SET_HT_OP_ELE_2ND_CHL_OFFSET(ht_op, SCN);
8313
break;
8314
}
8315
if (bw >= CHANNEL_WIDTH_40)
8316
SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op, 1);
8317
else
8318
SET_HT_OP_ELE_STA_CHL_WIDTH(ht_op, 0);
8319
c = rtw_set_ie(c, WLAN_EID_HT_OPERATION, HT_OP_IE_LEN, ht_op, NULL);
8320
}
8321
#endif /* defined(CONFIG_80211N_HT) */
8322
8323
#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8324
if (vht) {
8325
struct ieee80211_sta_vht_cap *sta_vht_cap = &wiphy->bands[chan->band]->vht_cap;
8326
u8 vht_cap[VHT_CAP_IE_LEN];
8327
u8 vht_op[VHT_OP_IE_LEN];
8328
u8 cch = rtw_get_center_ch(ch, bw, offset);
8329
8330
_rtw_memset(vht_op, 0, VHT_OP_IE_LEN);
8331
8332
/* WLAN_EID_VHT_CAPABILITY */
8333
_rtw_memcpy(vht_cap, &sta_vht_cap->cap, 4);
8334
_rtw_memcpy(vht_cap + 4, &sta_vht_cap->vht_mcs, 8);
8335
c = rtw_set_ie(c, WLAN_EID_VHT_CAPABILITY, VHT_CAP_IE_LEN, vht_cap, NULL);
8336
8337
/* WLAN_EID_VHT_OPERATION */
8338
if (bw < CHANNEL_WIDTH_80) {
8339
SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op, 0);
8340
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op, 0);
8341
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op, 0);
8342
} else if (bw == CHANNEL_WIDTH_80) {
8343
SET_VHT_OPERATION_ELE_CHL_WIDTH(vht_op, 1);
8344
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ1(vht_op, cch);
8345
SET_VHT_OPERATION_ELE_CHL_CENTER_FREQ2(vht_op, 0);
8346
} else {
8347
RTW_ERR(FUNC_ADPT_FMT" unsupported BW:%u\n", FUNC_ADPT_ARG(adapter), bw);
8348
rtw_warn_on(1);
8349
rtw_mfree(ies, len);
8350
goto exit;
8351
}
8352
8353
/* Hard code 1 stream, MCS0-7 is a min Basic VHT MCS rates */
8354
vht_op[3] = 0xfc;
8355
vht_op[4] = 0xff;
8356
c = rtw_set_ie(c, WLAN_EID_VHT_OPERATION, VHT_OP_IE_LEN, vht_op, NULL);
8357
}
8358
#endif /* defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
8359
8360
/* Mesh ID */
8361
c = rtw_set_ie_mesh_id(c, NULL, minfo->mesh_id, minfo->mesh_id_len);
8362
8363
/* Mesh configuration */
8364
c = rtw_set_ie_mesh_config(c, NULL
8365
, minfo->mesh_pp_id
8366
, minfo->mesh_pm_id
8367
, minfo->mesh_cc_id
8368
, minfo->mesh_sp_id
8369
, minfo->mesh_auth_id
8370
, 0, 0, 0
8371
, 1
8372
, 0, 0
8373
, mcfg->dot11MeshForwarding
8374
, 0, 0, 0
8375
);
8376
8377
#if DBG_RTW_CFG80211_MESH_CONF
8378
RTW_INFO(FUNC_ADPT_FMT" ies_len:%u\n", FUNC_ADPT_ARG(adapter), len);
8379
dump_ies(RTW_DBGDUMP, ies + _BEACON_IE_OFFSET_, len - _BEACON_IE_OFFSET_);
8380
#endif
8381
8382
exit:
8383
if (ies)
8384
*ies_len = len;
8385
return ies;
8386
}
8387
8388
static int cfg80211_rtw_get_mesh_config(struct wiphy *wiphy, struct net_device *dev
8389
, struct mesh_config *conf)
8390
{
8391
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8392
struct rtw_mesh_cfg *mesh_cfg = &adapter->mesh_cfg;
8393
int ret = 0;
8394
8395
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
8396
8397
/* driver MPM */
8398
conf->dot11MeshRetryTimeout = 0;
8399
conf->dot11MeshConfirmTimeout = 0;
8400
conf->dot11MeshHoldingTimeout = 0;
8401
conf->dot11MeshMaxPeerLinks = mesh_cfg->max_peer_links;
8402
conf->dot11MeshMaxRetries = 0;
8403
8404
conf->dot11MeshTTL = mesh_cfg->dot11MeshTTL;
8405
conf->element_ttl = mesh_cfg->element_ttl;
8406
8407
/* driver MPM */
8408
conf->auto_open_plinks = 0;
8409
8410
/* TBD: synchronization */
8411
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8412
conf->dot11MeshNbrOffsetMaxNeighbor = 0;
8413
#endif
8414
8415
conf->dot11MeshHWMPmaxPREQretries = mesh_cfg->dot11MeshHWMPmaxPREQretries;
8416
conf->path_refresh_time = mesh_cfg->path_refresh_time;
8417
conf->min_discovery_timeout = mesh_cfg->min_discovery_timeout;
8418
conf->dot11MeshHWMPactivePathTimeout = mesh_cfg->dot11MeshHWMPactivePathTimeout;
8419
conf->dot11MeshHWMPpreqMinInterval = mesh_cfg->dot11MeshHWMPpreqMinInterval;
8420
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
8421
conf->dot11MeshHWMPperrMinInterval = mesh_cfg->dot11MeshHWMPperrMinInterval;
8422
#endif
8423
conf->dot11MeshHWMPnetDiameterTraversalTime = mesh_cfg->dot11MeshHWMPnetDiameterTraversalTime;
8424
conf->dot11MeshHWMPRootMode = mesh_cfg->dot11MeshHWMPRootMode;
8425
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
8426
conf->dot11MeshHWMPRannInterval = mesh_cfg->dot11MeshHWMPRannInterval;
8427
#endif
8428
conf->dot11MeshGateAnnouncementProtocol = mesh_cfg->dot11MeshGateAnnouncementProtocol;
8429
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 4, 0))
8430
conf->dot11MeshForwarding = mesh_cfg->dot11MeshForwarding;
8431
conf->rssi_threshold = mesh_cfg->rssi_threshold;
8432
#endif
8433
8434
/* TBD */
8435
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
8436
conf->ht_opmode = 0xffff;
8437
#endif
8438
8439
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
8440
conf->dot11MeshHWMPactivePathToRootTimeout = mesh_cfg->dot11MeshHWMPactivePathToRootTimeout;
8441
conf->dot11MeshHWMProotInterval = mesh_cfg->dot11MeshHWMProotInterval;
8442
conf->dot11MeshHWMPconfirmationInterval = mesh_cfg->dot11MeshHWMPconfirmationInterval;
8443
#endif
8444
8445
/* TBD: power save */
8446
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
8447
conf->power_mode = NL80211_MESH_POWER_ACTIVE;
8448
conf->dot11MeshAwakeWindowDuration = 0;
8449
#endif
8450
8451
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8452
conf->plink_timeout = mesh_cfg->plink_timeout;
8453
#endif
8454
8455
return ret;
8456
}
8457
8458
static void rtw_mbss_info_change_notify(_adapter *adapter, bool minfo_changed, bool need_work)
8459
{
8460
if (need_work)
8461
rtw_mesh_work(&adapter->mesh_work);
8462
}
8463
8464
static int cfg80211_rtw_update_mesh_config(struct wiphy *wiphy, struct net_device *dev
8465
, u32 mask, const struct mesh_config *nconf)
8466
{
8467
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8468
int ret = 0;
8469
bool minfo_changed = _FALSE, need_work = _FALSE;
8470
8471
RTW_INFO(FUNC_ADPT_FMT" mask:0x%08x\n", FUNC_ADPT_ARG(adapter), mask);
8472
8473
rtw_cfg80211_mesh_cfg_set(adapter, nconf, mask);
8474
update_beacon(adapter, WLAN_EID_MESH_CONFIG, NULL, _TRUE, 0);
8475
#if CONFIG_RTW_MESH_CTO_MGATE_CARRIER
8476
if (rtw_mesh_cto_mgate_required(adapter))
8477
rtw_netif_carrier_off(adapter->pnetdev);
8478
else
8479
rtw_netif_carrier_on(adapter->pnetdev);
8480
#endif
8481
need_work = rtw_ieee80211_mesh_root_setup(adapter);
8482
8483
rtw_mbss_info_change_notify(adapter, minfo_changed, need_work);
8484
8485
return ret;
8486
}
8487
8488
static int cfg80211_rtw_join_mesh(struct wiphy *wiphy, struct net_device *dev,
8489
const struct mesh_config *conf, const struct mesh_setup *setup)
8490
{
8491
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8492
u8 *ies = NULL;
8493
uint ies_len;
8494
int ret = 0;
8495
8496
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
8497
8498
#if DBG_RTW_CFG80211_MESH_CONF
8499
RTW_INFO(FUNC_ADPT_FMT" mesh_setup:\n", FUNC_ADPT_ARG(adapter));
8500
dump_mesh_setup(RTW_DBGDUMP, wiphy, setup);
8501
RTW_INFO(FUNC_ADPT_FMT" mesh_config:\n", FUNC_ADPT_ARG(adapter));
8502
dump_mesh_config(RTW_DBGDUMP, conf);
8503
#endif
8504
8505
if (rtw_cfg80211_sync_iftype(adapter) != _SUCCESS) {
8506
ret = -ENOTSUPP;
8507
goto exit;
8508
}
8509
8510
/* initialization */
8511
rtw_mesh_init_mesh_info(adapter);
8512
8513
/* apply cfg80211 settings*/
8514
rtw_cfg80211_mesh_info_set_profile(&adapter->mesh_info, setup);
8515
rtw_cfg80211_mesh_cfg_set(adapter, conf, 0xFFFFFFFF);
8516
8517
/* apply cfg80211 settings (join only) */
8518
rtw_mesh_cfg_init_max_peer_links(adapter, conf->dot11MeshMaxPeerLinks);
8519
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0))
8520
rtw_mesh_cfg_init_plink_timeout(adapter, conf->plink_timeout);
8521
#endif
8522
8523
rtw_ieee80211_mesh_root_setup(adapter);
8524
8525
ies = rtw_cfg80211_construct_mesh_beacon_ies(wiphy, adapter, conf, setup, &ies_len);
8526
if (!ies) {
8527
ret = -EINVAL;
8528
goto exit;
8529
}
8530
8531
/* start mbss */
8532
if (rtw_check_beacon_data(adapter, ies, ies_len) != _SUCCESS) {
8533
ret = -EINVAL;
8534
goto exit;
8535
}
8536
8537
rtw_mesh_work(&adapter->mesh_work);
8538
8539
exit:
8540
if (ies)
8541
rtw_mfree(ies, ies_len);
8542
if (ret)
8543
rtw_mesh_deinit_mesh_info(adapter);
8544
8545
return ret;
8546
}
8547
8548
static int cfg80211_rtw_leave_mesh(struct wiphy *wiphy, struct net_device *dev)
8549
{
8550
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8551
int ret = 0;
8552
8553
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
8554
8555
rtw_mesh_deinit_mesh_info(adapter);
8556
8557
rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11Infrastructure, 0);
8558
rtw_setopmode_cmd(adapter, Ndis802_11Infrastructure, RTW_CMDF_WAIT_ACK);
8559
8560
return ret;
8561
}
8562
8563
static int cfg80211_rtw_add_mpath(struct wiphy *wiphy, struct net_device *dev
8564
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
8565
, const u8 *dst, const u8 *next_hop
8566
#else
8567
, u8 *dst, u8 *next_hop
8568
#endif
8569
)
8570
{
8571
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8572
struct sta_priv *stapriv = &adapter->stapriv;
8573
struct sta_info *sta;
8574
struct rtw_mesh_path *mpath;
8575
int ret = 0;
8576
8577
rtw_rcu_read_lock();
8578
8579
sta = rtw_get_stainfo(stapriv, next_hop);
8580
if (!sta) {
8581
ret = -ENOENT;
8582
goto exit;
8583
}
8584
8585
mpath = rtw_mesh_path_add(adapter, dst);
8586
if (!mpath) {
8587
ret = -ENOENT;
8588
goto exit;
8589
}
8590
8591
rtw_mesh_path_fix_nexthop(mpath, sta);
8592
8593
exit:
8594
rtw_rcu_read_unlock();
8595
8596
return ret;
8597
}
8598
8599
static int cfg80211_rtw_del_mpath(struct wiphy *wiphy, struct net_device *dev
8600
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
8601
, const u8 *dst
8602
#else
8603
, u8 *dst
8604
#endif
8605
)
8606
{
8607
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8608
int ret = 0;
8609
8610
if (dst) {
8611
if (rtw_mesh_path_del(adapter, dst)) {
8612
ret = -ENOENT;
8613
goto exit;
8614
}
8615
} else {
8616
rtw_mesh_path_flush_by_iface(adapter);
8617
}
8618
8619
exit:
8620
return ret;
8621
}
8622
8623
static int cfg80211_rtw_change_mpath(struct wiphy *wiphy, struct net_device *dev
8624
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0))
8625
, const u8 *dst, const u8 *next_hop
8626
#else
8627
, u8 *dst, u8 *next_hop
8628
#endif
8629
)
8630
{
8631
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8632
struct sta_priv *stapriv = &adapter->stapriv;
8633
struct sta_info *sta;
8634
struct rtw_mesh_path *mpath;
8635
int ret = 0;
8636
8637
rtw_rcu_read_lock();
8638
8639
sta = rtw_get_stainfo(stapriv, next_hop);
8640
if (!sta) {
8641
ret = -ENOENT;
8642
goto exit;
8643
}
8644
8645
mpath = rtw_mesh_path_lookup(adapter, dst);
8646
if (!mpath) {
8647
ret = -ENOENT;
8648
goto exit;
8649
}
8650
8651
rtw_mesh_path_fix_nexthop(mpath, sta);
8652
8653
exit:
8654
rtw_rcu_read_unlock();
8655
8656
return ret;
8657
}
8658
8659
static void rtw_cfg80211_mpath_set_pinfo(struct rtw_mesh_path *mpath, u8 *next_hop, struct mpath_info *pinfo)
8660
{
8661
struct sta_info *next_hop_sta = rtw_rcu_dereference(mpath->next_hop);
8662
8663
if (next_hop_sta)
8664
_rtw_memcpy(next_hop, next_hop_sta->cmn.mac_addr, ETH_ALEN);
8665
else
8666
_rtw_memset(next_hop, 0, ETH_ALEN);
8667
8668
_rtw_memset(pinfo, 0, sizeof(*pinfo));
8669
8670
pinfo->generation = mpath->adapter->mesh_info.mesh_paths_generation;
8671
8672
pinfo->filled = 0
8673
| MPATH_INFO_FRAME_QLEN
8674
| MPATH_INFO_SN
8675
| MPATH_INFO_METRIC
8676
| MPATH_INFO_EXPTIME
8677
| MPATH_INFO_DISCOVERY_TIMEOUT
8678
| MPATH_INFO_DISCOVERY_RETRIES
8679
| MPATH_INFO_FLAGS
8680
;
8681
8682
pinfo->frame_qlen = mpath->frame_queue_len;
8683
pinfo->sn = mpath->sn;
8684
pinfo->metric = mpath->metric;
8685
if (rtw_time_after(mpath->exp_time, rtw_get_current_time()))
8686
pinfo->exptime = rtw_get_remaining_time_ms(mpath->exp_time);
8687
pinfo->discovery_timeout = rtw_systime_to_ms(mpath->discovery_timeout);
8688
pinfo->discovery_retries = mpath->discovery_retries;
8689
if (mpath->flags & RTW_MESH_PATH_ACTIVE)
8690
pinfo->flags |= NL80211_MPATH_FLAG_ACTIVE;
8691
if (mpath->flags & RTW_MESH_PATH_RESOLVING)
8692
pinfo->flags |= NL80211_MPATH_FLAG_RESOLVING;
8693
if (mpath->flags & RTW_MESH_PATH_SN_VALID)
8694
pinfo->flags |= NL80211_MPATH_FLAG_SN_VALID;
8695
if (mpath->flags & RTW_MESH_PATH_FIXED)
8696
pinfo->flags |= NL80211_MPATH_FLAG_FIXED;
8697
if (mpath->flags & RTW_MESH_PATH_RESOLVED)
8698
pinfo->flags |= NL80211_MPATH_FLAG_RESOLVED;
8699
}
8700
8701
static int cfg80211_rtw_get_mpath(struct wiphy *wiphy, struct net_device *dev, u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
8702
{
8703
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8704
struct rtw_mesh_path *mpath;
8705
int ret = 0;
8706
8707
rtw_rcu_read_lock();
8708
8709
mpath = rtw_mesh_path_lookup(adapter, dst);
8710
if (!mpath) {
8711
ret = -ENOENT;
8712
goto exit;
8713
}
8714
8715
rtw_cfg80211_mpath_set_pinfo(mpath, next_hop, pinfo);
8716
8717
exit:
8718
rtw_rcu_read_unlock();
8719
8720
return ret;
8721
}
8722
8723
static int cfg80211_rtw_dump_mpath(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *next_hop, struct mpath_info *pinfo)
8724
{
8725
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8726
struct rtw_mesh_path *mpath;
8727
int ret = 0;
8728
8729
rtw_rcu_read_lock();
8730
8731
mpath = rtw_mesh_path_lookup_by_idx(adapter, idx);
8732
if (!mpath) {
8733
ret = -ENOENT;
8734
goto exit;
8735
}
8736
8737
_rtw_memcpy(dst, mpath->dst, ETH_ALEN);
8738
rtw_cfg80211_mpath_set_pinfo(mpath, next_hop, pinfo);
8739
8740
exit:
8741
rtw_rcu_read_unlock();
8742
8743
return ret;
8744
}
8745
8746
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
8747
static void rtw_cfg80211_mpp_set_pinfo(struct rtw_mesh_path *mpath, u8 *mpp, struct mpath_info *pinfo)
8748
{
8749
_rtw_memcpy(mpp, mpath->mpp, ETH_ALEN);
8750
8751
_rtw_memset(pinfo, 0, sizeof(*pinfo));
8752
pinfo->generation = mpath->adapter->mesh_info.mpp_paths_generation;
8753
}
8754
8755
static int cfg80211_rtw_get_mpp(struct wiphy *wiphy, struct net_device *dev, u8 *dst, u8 *mpp, struct mpath_info *pinfo)
8756
{
8757
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8758
struct rtw_mesh_path *mpath;
8759
int ret = 0;
8760
8761
rtw_rcu_read_lock();
8762
8763
mpath = rtw_mpp_path_lookup(adapter, dst);
8764
if (!mpath) {
8765
ret = -ENOENT;
8766
goto exit;
8767
}
8768
8769
rtw_cfg80211_mpp_set_pinfo(mpath, mpp, pinfo);
8770
8771
exit:
8772
rtw_rcu_read_unlock();
8773
8774
return ret;
8775
}
8776
8777
static int cfg80211_rtw_dump_mpp(struct wiphy *wiphy, struct net_device *dev, int idx, u8 *dst, u8 *mpp, struct mpath_info *pinfo)
8778
{
8779
_adapter *adapter = (_adapter *)rtw_netdev_priv(dev);
8780
struct rtw_mesh_path *mpath;
8781
int ret = 0;
8782
8783
rtw_rcu_read_lock();
8784
8785
mpath = rtw_mpp_path_lookup_by_idx(adapter, idx);
8786
if (!mpath) {
8787
ret = -ENOENT;
8788
goto exit;
8789
}
8790
8791
_rtw_memcpy(dst, mpath->dst, ETH_ALEN);
8792
rtw_cfg80211_mpp_set_pinfo(mpath, mpp, pinfo);
8793
8794
exit:
8795
rtw_rcu_read_unlock();
8796
8797
return ret;
8798
}
8799
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) */
8800
8801
#endif /* defined(CONFIG_RTW_MESH) */
8802
8803
#if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
8804
static int cfg80211_rtw_sched_scan_start(struct wiphy *wiphy,
8805
struct net_device *dev,
8806
struct cfg80211_sched_scan_request *request)
8807
{
8808
8809
_adapter *padapter = (_adapter *)rtw_netdev_priv(dev);
8810
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8811
struct cfg80211_ssid *ssids;
8812
int n_ssids = 0;
8813
int interval = 0;
8814
int i = 0;
8815
u8 ret;
8816
8817
if (padapter->bup == _FALSE) {
8818
RTW_INFO("%s: net device is down.\n", __func__);
8819
return -EIO;
8820
}
8821
8822
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _TRUE ||
8823
check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE ||
8824
check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE) {
8825
RTW_INFO("%s: device is busy.\n", __func__);
8826
rtw_scan_abort(padapter);
8827
}
8828
8829
if (request == NULL) {
8830
RTW_INFO("%s: invalid cfg80211_requests parameters.\n", __func__);
8831
return -EINVAL;
8832
}
8833
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
8834
8835
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)
8836
interval = request->scan_plans->interval;
8837
#else
8838
interval = request->interval;
8839
#endif
8840
n_ssids = request->n_match_sets;
8841
ssids = (struct cfg80211_ssid *)rtw_zmalloc(n_ssids * sizeof(struct cfg80211_ssid));
8842
if(ssids == NULL) {
8843
RTW_ERR("Fail to allocate ssids for PNO\n");
8844
return -ENOMEM;
8845
}
8846
for (i=0;i<request->n_match_sets;i++) {
8847
ssids[i].ssid_len = request->match_sets[i].ssid.ssid_len;
8848
memcpy(ssids[i].ssid, request->match_sets[i].ssid.ssid,
8849
request->match_sets[i].ssid.ssid_len);
8850
}
8851
#else
8852
interval = request->interval;
8853
n_ssids = request->n_ssids;
8854
ssids = request->ssids;
8855
#endif
8856
ret = rtw_android_cfg80211_pno_setup(dev, ssids,
8857
n_ssids, interval);
8858
if (ret < 0) {
8859
RTW_INFO("%s ret: %d\n", __func__, ret);
8860
goto exit;
8861
}
8862
8863
ret = rtw_android_pno_enable(dev, _TRUE);
8864
if (ret < 0) {
8865
RTW_INFO("%s ret: %d\n", __func__, ret);
8866
goto exit;
8867
}
8868
exit:
8869
return ret;
8870
}
8871
8872
static int cfg80211_rtw_sched_scan_stop(struct wiphy *wiphy,
8873
struct net_device *dev)
8874
{
8875
return rtw_android_pno_enable(dev, _FALSE);
8876
}
8877
8878
int cfg80211_rtw_suspend(struct wiphy *wiphy, struct cfg80211_wowlan *wow) {
8879
RTW_DBG("==> %s\n",__func__);
8880
RTW_DBG("<== %s\n",__func__);
8881
return 0;
8882
}
8883
8884
int cfg80211_rtw_resume(struct wiphy *wiphy) {
8885
8886
_adapter *padapter;
8887
struct pwrctrl_priv *pwrpriv;
8888
struct mlme_priv *pmlmepriv;
8889
padapter = wiphy_to_adapter(wiphy);
8890
pwrpriv = adapter_to_pwrctl(padapter);
8891
pmlmepriv = &padapter->mlmepriv;
8892
struct sitesurvey_parm parm;
8893
int i, len;
8894
8895
8896
RTW_DBG("==> %s\n",__func__);
8897
if (pwrpriv->wowlan_last_wake_reason == RX_PNO) {
8898
8899
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
8900
_irqL irqL;
8901
int PNOWakeupScanWaitCnt = 0;
8902
8903
rtw_cfg80211_disconnected(padapter->rtw_wdev, 0, NULL, 0, 1, GFP_ATOMIC);
8904
8905
rtw_init_sitesurvey_parm(padapter, &parm);
8906
for (i=0;i<pwrpriv->pnlo_info->ssid_num && i < RTW_SSID_SCAN_AMOUNT; i++) {
8907
len = pwrpriv->pno_ssid_list->node[i].SSID_len;
8908
_rtw_memcpy(&parm.ssid[i].Ssid, pwrpriv->pno_ssid_list->node[i].SSID, len);
8909
parm.ssid[i].SsidLength = len;
8910
}
8911
parm.ssid_num = pwrpriv->pnlo_info->ssid_num;
8912
8913
_enter_critical_bh(&pmlmepriv->lock, &irqL);
8914
//This modification fix PNO wakeup reconnect issue with hidden SSID AP.
8915
//rtw_sitesurvey_cmd(padapter, NULL);
8916
rtw_sitesurvey_cmd(padapter, &parm);
8917
_exit_critical_bh(&pmlmepriv->lock, &irqL);
8918
8919
for (PNOWakeupScanWaitCnt = 0; PNOWakeupScanWaitCnt < 10; PNOWakeupScanWaitCnt++) {
8920
if(check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == _FALSE)
8921
break;
8922
rtw_msleep_os(1000);
8923
}
8924
8925
_enter_critical_bh(&pmlmepriv->lock, &irqL);
8926
cfg80211_sched_scan_results(padapter->rtw_wdev->wiphy);
8927
_exit_critical_bh(&pmlmepriv->lock, &irqL);
8928
8929
}
8930
RTW_DBG("<== %s\n",__func__);
8931
return 0;
8932
8933
}
8934
#endif /* CONFIG_PNO_SUPPORT */
8935
8936
static int rtw_cfg80211_set_beacon_wpsp2pie(struct net_device *ndev, char *buf, int len)
8937
{
8938
int ret = 0;
8939
uint wps_ielen = 0;
8940
u8 *wps_ie;
8941
u32 p2p_ielen = 0;
8942
u8 wps_oui[8] = {0x0, 0x50, 0xf2, 0x04};
8943
u8 *p2p_ie;
8944
u32 wfd_ielen = 0;
8945
u8 *wfd_ie;
8946
_adapter *padapter = (_adapter *)rtw_netdev_priv(ndev);
8947
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8948
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8949
8950
RTW_INFO(FUNC_NDEV_FMT" ielen=%d\n", FUNC_NDEV_ARG(ndev), len);
8951
8952
if (len > 0) {
8953
wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
8954
if (wps_ie) {
8955
#ifdef CONFIG_DEBUG_CFG80211
8956
RTW_INFO("bcn_wps_ielen=%d\n", wps_ielen);
8957
#endif
8958
8959
if (pmlmepriv->wps_beacon_ie) {
8960
u32 free_len = pmlmepriv->wps_beacon_ie_len;
8961
pmlmepriv->wps_beacon_ie_len = 0;
8962
rtw_mfree(pmlmepriv->wps_beacon_ie, free_len);
8963
pmlmepriv->wps_beacon_ie = NULL;
8964
}
8965
8966
pmlmepriv->wps_beacon_ie = rtw_malloc(wps_ielen);
8967
if (pmlmepriv->wps_beacon_ie == NULL) {
8968
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
8969
return -EINVAL;
8970
8971
}
8972
8973
_rtw_memcpy(pmlmepriv->wps_beacon_ie, wps_ie, wps_ielen);
8974
pmlmepriv->wps_beacon_ie_len = wps_ielen;
8975
8976
update_beacon(padapter, _VENDOR_SPECIFIC_IE_, wps_oui, _TRUE, RTW_CMDF_WAIT_ACK);
8977
8978
}
8979
8980
/* buf += wps_ielen; */
8981
/* len -= wps_ielen; */
8982
8983
#ifdef CONFIG_P2P
8984
p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
8985
if (p2p_ie) {
8986
#ifdef CONFIG_DEBUG_CFG80211
8987
RTW_INFO("bcn_p2p_ielen=%d\n", p2p_ielen);
8988
#endif
8989
8990
if (pmlmepriv->p2p_beacon_ie) {
8991
u32 free_len = pmlmepriv->p2p_beacon_ie_len;
8992
pmlmepriv->p2p_beacon_ie_len = 0;
8993
rtw_mfree(pmlmepriv->p2p_beacon_ie, free_len);
8994
pmlmepriv->p2p_beacon_ie = NULL;
8995
}
8996
8997
pmlmepriv->p2p_beacon_ie = rtw_malloc(p2p_ielen);
8998
if (pmlmepriv->p2p_beacon_ie == NULL) {
8999
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9000
return -EINVAL;
9001
9002
}
9003
9004
_rtw_memcpy(pmlmepriv->p2p_beacon_ie, p2p_ie, p2p_ielen);
9005
pmlmepriv->p2p_beacon_ie_len = p2p_ielen;
9006
9007
}
9008
#endif /* CONFIG_P2P */
9009
9010
9011
#ifdef CONFIG_WFD
9012
wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
9013
if (wfd_ie) {
9014
#ifdef CONFIG_DEBUG_CFG80211
9015
RTW_INFO("bcn_wfd_ielen=%d\n", wfd_ielen);
9016
#endif
9017
9018
if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_BEACON_IE, wfd_ie, wfd_ielen) != _SUCCESS)
9019
return -EINVAL;
9020
}
9021
#endif /* CONFIG_WFD */
9022
9023
pmlmeext->bstart_bss = _TRUE;
9024
9025
}
9026
9027
return ret;
9028
9029
}
9030
9031
static int rtw_cfg80211_set_probe_resp_wpsp2pie(struct net_device *net, char *buf, int len)
9032
{
9033
int ret = 0;
9034
uint wps_ielen = 0;
9035
u8 *wps_ie;
9036
u32 p2p_ielen = 0;
9037
u8 *p2p_ie;
9038
u32 wfd_ielen = 0;
9039
u8 *wfd_ie;
9040
_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
9041
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9042
9043
#ifdef CONFIG_DEBUG_CFG80211
9044
RTW_INFO("%s, ielen=%d\n", __func__, len);
9045
#endif
9046
9047
if (len > 0) {
9048
wps_ie = rtw_get_wps_ie(buf, len, NULL, &wps_ielen);
9049
if (wps_ie) {
9050
uint attr_contentlen = 0;
9051
u16 uconfig_method, *puconfig_method = NULL;
9052
9053
#ifdef CONFIG_DEBUG_CFG80211
9054
RTW_INFO("probe_resp_wps_ielen=%d\n", wps_ielen);
9055
#endif
9056
9057
if (check_fwstate(pmlmepriv, WIFI_UNDER_WPS)) {
9058
u8 sr = 0;
9059
rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
9060
9061
if (sr != 0)
9062
RTW_INFO("%s, got sr\n", __func__);
9063
else {
9064
RTW_INFO("GO mode process WPS under site-survey, sr no set\n");
9065
return ret;
9066
}
9067
}
9068
9069
if (pmlmepriv->wps_probe_resp_ie) {
9070
u32 free_len = pmlmepriv->wps_probe_resp_ie_len;
9071
pmlmepriv->wps_probe_resp_ie_len = 0;
9072
rtw_mfree(pmlmepriv->wps_probe_resp_ie, free_len);
9073
pmlmepriv->wps_probe_resp_ie = NULL;
9074
}
9075
9076
pmlmepriv->wps_probe_resp_ie = rtw_malloc(wps_ielen);
9077
if (pmlmepriv->wps_probe_resp_ie == NULL) {
9078
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9079
return -EINVAL;
9080
9081
}
9082
9083
/* add PUSH_BUTTON config_method by driver self in wpsie of probe_resp at GO Mode */
9084
puconfig_method = (u16 *)rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_CONF_METHOD , NULL, &attr_contentlen);
9085
if (puconfig_method != NULL) {
9086
/* struct registry_priv *pregistrypriv = &padapter->registrypriv; */
9087
struct wireless_dev *wdev = padapter->rtw_wdev;
9088
9089
#ifdef CONFIG_DEBUG_CFG80211
9090
/* printk("config_method in wpsie of probe_resp = 0x%x\n", be16_to_cpu(*puconfig_method)); */
9091
#endif
9092
9093
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
9094
/* for WIFI-DIRECT LOGO 4.2.2, AUTO GO can't set PUSH_BUTTON flags */
9095
if (wdev->iftype == NL80211_IFTYPE_P2P_GO) {
9096
uconfig_method = WPS_CM_PUSH_BUTTON;
9097
uconfig_method = cpu_to_be16(uconfig_method);
9098
9099
*puconfig_method &= ~uconfig_method;
9100
}
9101
#endif
9102
}
9103
9104
_rtw_memcpy(pmlmepriv->wps_probe_resp_ie, wps_ie, wps_ielen);
9105
pmlmepriv->wps_probe_resp_ie_len = wps_ielen;
9106
9107
}
9108
9109
/* buf += wps_ielen; */
9110
/* len -= wps_ielen; */
9111
9112
#ifdef CONFIG_P2P
9113
p2p_ie = rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen);
9114
if (p2p_ie) {
9115
u8 is_GO = _FALSE;
9116
u32 attr_contentlen = 0;
9117
u16 cap_attr = 0;
9118
9119
#ifdef CONFIG_DEBUG_CFG80211
9120
RTW_INFO("probe_resp_p2p_ielen=%d\n", p2p_ielen);
9121
#endif
9122
9123
/* Check P2P Capability ATTR */
9124
if (rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_CAPABILITY, (u8 *)&cap_attr, (uint *) &attr_contentlen)) {
9125
u8 grp_cap = 0;
9126
/* RTW_INFO( "[%s] Got P2P Capability Attr!!\n", __FUNCTION__ ); */
9127
cap_attr = le16_to_cpu(cap_attr);
9128
grp_cap = (u8)((cap_attr >> 8) & 0xff);
9129
9130
is_GO = (grp_cap & BIT(0)) ? _TRUE : _FALSE;
9131
9132
if (is_GO)
9133
RTW_INFO("Got P2P Capability Attr, grp_cap=0x%x, is_GO\n", grp_cap);
9134
}
9135
9136
9137
if (is_GO == _FALSE) {
9138
if (pmlmepriv->p2p_probe_resp_ie) {
9139
u32 free_len = pmlmepriv->p2p_probe_resp_ie_len;
9140
pmlmepriv->p2p_probe_resp_ie_len = 0;
9141
rtw_mfree(pmlmepriv->p2p_probe_resp_ie, free_len);
9142
pmlmepriv->p2p_probe_resp_ie = NULL;
9143
}
9144
9145
pmlmepriv->p2p_probe_resp_ie = rtw_malloc(p2p_ielen);
9146
if (pmlmepriv->p2p_probe_resp_ie == NULL) {
9147
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9148
return -EINVAL;
9149
9150
}
9151
_rtw_memcpy(pmlmepriv->p2p_probe_resp_ie, p2p_ie, p2p_ielen);
9152
pmlmepriv->p2p_probe_resp_ie_len = p2p_ielen;
9153
} else {
9154
if (pmlmepriv->p2p_go_probe_resp_ie) {
9155
u32 free_len = pmlmepriv->p2p_go_probe_resp_ie_len;
9156
pmlmepriv->p2p_go_probe_resp_ie_len = 0;
9157
rtw_mfree(pmlmepriv->p2p_go_probe_resp_ie, free_len);
9158
pmlmepriv->p2p_go_probe_resp_ie = NULL;
9159
}
9160
9161
pmlmepriv->p2p_go_probe_resp_ie = rtw_malloc(p2p_ielen);
9162
if (pmlmepriv->p2p_go_probe_resp_ie == NULL) {
9163
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9164
return -EINVAL;
9165
9166
}
9167
_rtw_memcpy(pmlmepriv->p2p_go_probe_resp_ie, p2p_ie, p2p_ielen);
9168
pmlmepriv->p2p_go_probe_resp_ie_len = p2p_ielen;
9169
}
9170
9171
}
9172
#endif /* CONFIG_P2P */
9173
9174
9175
#ifdef CONFIG_WFD
9176
wfd_ie = rtw_get_wfd_ie(buf, len, NULL, &wfd_ielen);
9177
if (wfd_ie) {
9178
#ifdef CONFIG_DEBUG_CFG80211
9179
RTW_INFO("probe_resp_wfd_ielen=%d\n", wfd_ielen);
9180
#endif
9181
9182
if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_PROBE_RESP_IE, wfd_ie, wfd_ielen) != _SUCCESS)
9183
return -EINVAL;
9184
}
9185
#endif /* CONFIG_WFD */
9186
9187
}
9188
9189
return ret;
9190
9191
}
9192
9193
static int rtw_cfg80211_set_assoc_resp_wpsp2pie(struct net_device *net, char *buf, int len)
9194
{
9195
int ret = 0;
9196
_adapter *padapter = (_adapter *)rtw_netdev_priv(net);
9197
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
9198
u8 *ie;
9199
u32 ie_len;
9200
9201
RTW_INFO("%s, ielen=%d\n", __func__, len);
9202
9203
if (len <= 0)
9204
goto exit;
9205
9206
ie = rtw_get_wps_ie(buf, len, NULL, &ie_len);
9207
if (ie && ie_len) {
9208
if (pmlmepriv->wps_assoc_resp_ie) {
9209
u32 free_len = pmlmepriv->wps_assoc_resp_ie_len;
9210
9211
pmlmepriv->wps_assoc_resp_ie_len = 0;
9212
rtw_mfree(pmlmepriv->wps_assoc_resp_ie, free_len);
9213
pmlmepriv->wps_assoc_resp_ie = NULL;
9214
}
9215
9216
pmlmepriv->wps_assoc_resp_ie = rtw_malloc(ie_len);
9217
if (pmlmepriv->wps_assoc_resp_ie == NULL) {
9218
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9219
return -EINVAL;
9220
}
9221
_rtw_memcpy(pmlmepriv->wps_assoc_resp_ie, ie, ie_len);
9222
pmlmepriv->wps_assoc_resp_ie_len = ie_len;
9223
}
9224
9225
ie = rtw_get_p2p_ie(buf, len, NULL, &ie_len);
9226
if (ie && ie_len) {
9227
if (pmlmepriv->p2p_assoc_resp_ie) {
9228
u32 free_len = pmlmepriv->p2p_assoc_resp_ie_len;
9229
9230
pmlmepriv->p2p_assoc_resp_ie_len = 0;
9231
rtw_mfree(pmlmepriv->p2p_assoc_resp_ie, free_len);
9232
pmlmepriv->p2p_assoc_resp_ie = NULL;
9233
}
9234
9235
pmlmepriv->p2p_assoc_resp_ie = rtw_malloc(ie_len);
9236
if (pmlmepriv->p2p_assoc_resp_ie == NULL) {
9237
RTW_INFO("%s()-%d: rtw_malloc() ERROR!\n", __FUNCTION__, __LINE__);
9238
return -EINVAL;
9239
}
9240
_rtw_memcpy(pmlmepriv->p2p_assoc_resp_ie, ie, ie_len);
9241
pmlmepriv->p2p_assoc_resp_ie_len = ie_len;
9242
}
9243
9244
#ifdef CONFIG_WFD
9245
ie = rtw_get_wfd_ie(buf, len, NULL, &ie_len);
9246
if (rtw_mlme_update_wfd_ie_data(pmlmepriv, MLME_ASSOC_RESP_IE, ie, ie_len) != _SUCCESS)
9247
return -EINVAL;
9248
#endif
9249
9250
exit:
9251
return ret;
9252
}
9253
9254
int rtw_cfg80211_set_mgnt_wpsp2pie(struct net_device *net, char *buf, int len,
9255
int type)
9256
{
9257
int ret = 0;
9258
uint wps_ielen = 0;
9259
u32 p2p_ielen = 0;
9260
9261
#ifdef CONFIG_DEBUG_CFG80211
9262
RTW_INFO("%s, ielen=%d\n", __func__, len);
9263
#endif
9264
9265
if ((rtw_get_wps_ie(buf, len, NULL, &wps_ielen) && (wps_ielen > 0))
9266
#ifdef CONFIG_P2P
9267
|| (rtw_get_p2p_ie(buf, len, NULL, &p2p_ielen) && (p2p_ielen > 0))
9268
#endif
9269
) {
9270
if (net != NULL) {
9271
switch (type) {
9272
case 0x1: /* BEACON */
9273
ret = rtw_cfg80211_set_beacon_wpsp2pie(net, buf, len);
9274
break;
9275
case 0x2: /* PROBE_RESP */
9276
ret = rtw_cfg80211_set_probe_resp_wpsp2pie(net, buf, len);
9277
#ifdef CONFIG_P2P
9278
if (ret == 0)
9279
adapter_wdev_data((_adapter *)rtw_netdev_priv(net))->probe_resp_ie_update_time = rtw_get_current_time();
9280
#endif
9281
break;
9282
case 0x4: /* ASSOC_RESP */
9283
ret = rtw_cfg80211_set_assoc_resp_wpsp2pie(net, buf, len);
9284
break;
9285
}
9286
}
9287
}
9288
9289
return ret;
9290
9291
}
9292
9293
#ifdef CONFIG_80211N_HT
9294
static void rtw_cfg80211_init_ht_capab_ex(_adapter *padapter
9295
, struct ieee80211_sta_ht_cap *ht_cap, BAND_TYPE band, u8 rf_type)
9296
{
9297
struct registry_priv *pregistrypriv = &padapter->registrypriv;
9298
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9299
struct ht_priv *phtpriv = &pmlmepriv->htpriv;
9300
u8 stbc_rx_enable = _FALSE;
9301
9302
rtw_ht_use_default_setting(padapter);
9303
9304
/* RX LDPC */
9305
if (TEST_FLAG(phtpriv->ldpc_cap, LDPC_HT_ENABLE_RX))
9306
ht_cap->cap |= IEEE80211_HT_CAP_LDPC_CODING;
9307
9308
/* TX STBC */
9309
if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_TX))
9310
ht_cap->cap |= IEEE80211_HT_CAP_TX_STBC;
9311
9312
/* RX STBC */
9313
if (TEST_FLAG(phtpriv->stbc_cap, STBC_HT_ENABLE_RX)) {
9314
/*rtw_rx_stbc 0: disable, bit(0):enable 2.4g, bit(1):enable 5g*/
9315
if (band == BAND_ON_2_4G)
9316
stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(0)) ? _TRUE : _FALSE;
9317
if (band == BAND_ON_5G)
9318
stbc_rx_enable = (pregistrypriv->rx_stbc & BIT(1)) ? _TRUE : _FALSE;
9319
9320
if (stbc_rx_enable) {
9321
switch (rf_type) {
9322
case RF_1T1R:
9323
ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/*RX STBC One spatial stream*/
9324
break;
9325
9326
case RF_2T2R:
9327
case RF_1T2R:
9328
ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
9329
break;
9330
case RF_3T3R:
9331
case RF_3T4R:
9332
case RF_4T4R:
9333
ht_cap->cap |= IEEE80211_HT_CAP_RX_STBC_1R;/* Only one spatial-stream STBC RX is supported */
9334
break;
9335
default:
9336
RTW_INFO("[warning] rf_type %d is not expected\n", rf_type);
9337
break;
9338
}
9339
}
9340
}
9341
}
9342
9343
static void rtw_cfg80211_init_ht_capab(_adapter *padapter
9344
, struct ieee80211_sta_ht_cap *ht_cap, BAND_TYPE band, u8 rf_type)
9345
{
9346
struct registry_priv *regsty = &padapter->registrypriv;
9347
u8 rx_nss = 0;
9348
9349
if (!regsty->ht_enable || !is_supported_ht(regsty->wireless_mode))
9350
return;
9351
9352
ht_cap->ht_supported = 1;
9353
9354
ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
9355
IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_SGI_20 |
9356
IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
9357
rtw_cfg80211_init_ht_capab_ex(padapter, ht_cap, band, rf_type);
9358
9359
/*
9360
*Maximum length of AMPDU that the STA can receive.
9361
*Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
9362
*/
9363
ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
9364
9365
/*Minimum MPDU start spacing , */
9366
ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
9367
9368
ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
9369
9370
rx_nss = GET_HAL_RX_NSS(padapter);
9371
switch (rx_nss) {
9372
case 1:
9373
ht_cap->mcs.rx_mask[0] = 0xFF;
9374
break;
9375
case 2:
9376
ht_cap->mcs.rx_mask[0] = 0xFF;
9377
ht_cap->mcs.rx_mask[1] = 0xFF;
9378
break;
9379
case 3:
9380
ht_cap->mcs.rx_mask[0] = 0xFF;
9381
ht_cap->mcs.rx_mask[1] = 0xFF;
9382
ht_cap->mcs.rx_mask[2] = 0xFF;
9383
break;
9384
case 4:
9385
ht_cap->mcs.rx_mask[0] = 0xFF;
9386
ht_cap->mcs.rx_mask[1] = 0xFF;
9387
ht_cap->mcs.rx_mask[2] = 0xFF;
9388
ht_cap->mcs.rx_mask[3] = 0xFF;
9389
break;
9390
default:
9391
rtw_warn_on(1);
9392
RTW_INFO("%s, error rf_type=%d, rx_nss=%d\n", __func__, rf_type, rx_nss);
9393
};
9394
9395
ht_cap->mcs.rx_highest = cpu_to_le16(
9396
rtw_ht_mcs_rate(hal_is_bw_support(padapter, CHANNEL_WIDTH_40)
9397
, hal_is_bw_support(padapter, CHANNEL_WIDTH_40) ? ht_cap->cap & IEEE80211_HT_CAP_SGI_40 : ht_cap->cap & IEEE80211_HT_CAP_SGI_20
9398
, ht_cap->mcs.rx_mask) / 10);
9399
}
9400
#endif /* CONFIG_80211N_HT */
9401
9402
#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9403
static void rtw_cfg80211_init_vht_capab(_adapter *padapter
9404
, struct ieee80211_sta_vht_cap *sta_vht_cap, BAND_TYPE band, u8 rf_type)
9405
{
9406
struct registry_priv *regsty = &padapter->registrypriv;
9407
u8 vht_cap_ie[2 + 12] = {0};
9408
9409
if (!REGSTY_IS_11AC_ENABLE(regsty) || !is_supported_vht(regsty->wireless_mode))
9410
return;
9411
9412
rtw_vht_use_default_setting(padapter);
9413
rtw_build_vht_cap_ie(padapter, vht_cap_ie);
9414
9415
sta_vht_cap->vht_supported = 1;
9416
9417
_rtw_memcpy(&sta_vht_cap->cap, vht_cap_ie + 2, 4);
9418
_rtw_memcpy(&sta_vht_cap->vht_mcs, vht_cap_ie + 2 + 4, 8);
9419
}
9420
#endif /* defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0)) */
9421
9422
void rtw_cfg80211_init_wdev_data(_adapter *padapter)
9423
{
9424
#ifdef CONFIG_CONCURRENT_MODE
9425
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
9426
9427
ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
9428
#endif
9429
}
9430
9431
void rtw_cfg80211_init_wiphy(_adapter *padapter)
9432
{
9433
u8 rf_type;
9434
struct ieee80211_supported_band *band;
9435
struct wireless_dev *pwdev = padapter->rtw_wdev;
9436
struct wiphy *wiphy = pwdev->wiphy;
9437
9438
rf_type = GET_HAL_RFPATH(padapter);
9439
RTW_INFO("%s:rf_type=%d\n", __func__, rf_type);
9440
9441
if (IsSupported24G(padapter->registrypriv.wireless_mode)) {
9442
band = wiphy->bands[NL80211_BAND_2GHZ];
9443
if (band) {
9444
#if defined(CONFIG_80211N_HT)
9445
rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_2_4G, rf_type);
9446
#endif
9447
}
9448
}
9449
#ifdef CONFIG_IEEE80211_BAND_5GHZ
9450
if (is_supported_5g(padapter->registrypriv.wireless_mode)) {
9451
band = wiphy->bands[NL80211_BAND_5GHZ];
9452
if (band) {
9453
#if defined(CONFIG_80211N_HT)
9454
rtw_cfg80211_init_ht_capab(padapter, &band->ht_cap, BAND_ON_5G, rf_type);
9455
#endif
9456
#if defined(CONFIG_80211AC_VHT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9457
rtw_cfg80211_init_vht_capab(padapter, &band->vht_cap, BAND_ON_5G, rf_type);
9458
#endif
9459
}
9460
}
9461
#endif
9462
9463
/* copy mac_addr to wiphy */
9464
_rtw_memcpy(wiphy->perm_addr, adapter_mac_addr(padapter), ETH_ALEN);
9465
9466
}
9467
9468
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
9469
struct ieee80211_iface_limit rtw_limits[] = {
9470
{
9471
.max = 2,
9472
.types = BIT(NL80211_IFTYPE_STATION)
9473
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
9474
| BIT(NL80211_IFTYPE_P2P_CLIENT)
9475
#endif
9476
},
9477
#ifdef CONFIG_AP_MODE
9478
{
9479
.max = 1,
9480
.types = BIT(NL80211_IFTYPE_AP)
9481
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
9482
| BIT(NL80211_IFTYPE_P2P_GO)
9483
#endif
9484
},
9485
#endif
9486
#if defined(RTW_DEDICATED_P2P_DEVICE)
9487
{
9488
.max = 1,
9489
.types = BIT(NL80211_IFTYPE_P2P_DEVICE)
9490
},
9491
#endif
9492
#if defined(CONFIG_RTW_MESH)
9493
{
9494
.max = 1,
9495
.types = BIT(NL80211_IFTYPE_MESH_POINT)
9496
},
9497
#endif
9498
};
9499
9500
struct ieee80211_iface_combination rtw_combinations[] = {
9501
{
9502
.limits = rtw_limits,
9503
.n_limits = ARRAY_SIZE(rtw_limits),
9504
#if defined(RTW_DEDICATED_P2P_DEVICE)
9505
.max_interfaces = 3,
9506
#else
9507
.max_interfaces = 2,
9508
#endif
9509
.num_different_channels = 1,
9510
},
9511
};
9512
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) */
9513
9514
static void rtw_cfg80211_preinit_wiphy(_adapter *adapter, struct wiphy *wiphy)
9515
{
9516
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
9517
struct registry_priv *regsty = dvobj_to_regsty(dvobj);
9518
9519
wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
9520
9521
wiphy->max_scan_ssids = RTW_SSID_SCAN_AMOUNT;
9522
wiphy->max_scan_ie_len = RTW_SCAN_IE_LEN_MAX;
9523
wiphy->max_num_pmkids = RTW_MAX_NUM_PMKIDS;
9524
9525
#if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
9526
wiphy->max_acl_mac_addrs = NUM_ACL;
9527
#endif
9528
9529
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38)) || defined(COMPAT_KERNEL_RELEASE)
9530
wiphy->max_remain_on_channel_duration = RTW_MAX_REMAIN_ON_CHANNEL_DURATION;
9531
#endif
9532
9533
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION)
9534
| BIT(NL80211_IFTYPE_ADHOC)
9535
#ifdef CONFIG_AP_MODE
9536
| BIT(NL80211_IFTYPE_AP)
9537
#ifdef CONFIG_WIFI_MONITOR
9538
| BIT(NL80211_IFTYPE_MONITOR)
9539
#endif
9540
#endif
9541
#if defined(CONFIG_P2P) && ((LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE))
9542
| BIT(NL80211_IFTYPE_P2P_CLIENT)
9543
| BIT(NL80211_IFTYPE_P2P_GO)
9544
#if defined(RTW_DEDICATED_P2P_DEVICE)
9545
| BIT(NL80211_IFTYPE_P2P_DEVICE)
9546
#endif
9547
#endif
9548
#ifdef CONFIG_RTW_MESH
9549
| BIT(NL80211_IFTYPE_MESH_POINT) /* 2.6.26 */
9550
#endif
9551
;
9552
9553
#if defined(CONFIG_ANDROID) && !defined(RTW_SINGLE_WIPHY)
9554
if (is_primary_adapter(adapter)) {
9555
wiphy->interface_modes &= ~(BIT(NL80211_IFTYPE_P2P_GO) | BIT(NL80211_IFTYPE_P2P_CLIENT));
9556
RTW_INFO("%s primary- don't set p2p capability\n", __func__);
9557
}
9558
#endif
9559
9560
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
9561
#ifdef CONFIG_AP_MODE
9562
wiphy->mgmt_stypes = rtw_cfg80211_default_mgmt_stypes;
9563
#endif /* CONFIG_AP_MODE */
9564
#endif
9565
9566
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
9567
#ifdef CONFIG_WIFI_MONITOR
9568
wiphy->software_iftypes |= BIT(NL80211_IFTYPE_MONITOR);
9569
#endif
9570
#endif
9571
9572
#if defined(RTW_SINGLE_WIPHY) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
9573
wiphy->iface_combinations = rtw_combinations;
9574
wiphy->n_iface_combinations = ARRAY_SIZE(rtw_combinations);
9575
#endif
9576
9577
wiphy->cipher_suites = rtw_cipher_suites;
9578
wiphy->n_cipher_suites = ARRAY_SIZE(rtw_cipher_suites);
9579
9580
if (IsSupported24G(adapter->registrypriv.wireless_mode))
9581
wiphy->bands[NL80211_BAND_2GHZ] = rtw_spt_band_alloc(BAND_ON_2_4G);
9582
9583
#ifdef CONFIG_IEEE80211_BAND_5GHZ
9584
if (is_supported_5g(adapter->registrypriv.wireless_mode))
9585
wiphy->bands[NL80211_BAND_5GHZ] = rtw_spt_band_alloc(BAND_ON_5G);
9586
#endif
9587
9588
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38) && LINUX_VERSION_CODE < KERNEL_VERSION(3, 0, 0))
9589
wiphy->flags |= WIPHY_FLAG_SUPPORTS_SEPARATE_DEFAULT_KEYS;
9590
#endif
9591
9592
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
9593
wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
9594
wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME;
9595
/* remove WIPHY_FLAG_OFFCHAN_TX, because we not support this feature */
9596
/* wiphy->flags |= WIPHY_FLAG_OFFCHAN_TX | WIPHY_FLAG_HAVE_AP_SME; */
9597
#endif
9598
9599
#if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) && \
9600
LINUX_VERSION_CODE < KERNEL_VERSION(4, 12, 0))
9601
wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
9602
#ifdef CONFIG_PNO_SUPPORT
9603
wiphy->max_sched_scan_ssids = MAX_PNO_LIST_COUNT;
9604
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0)
9605
wiphy->max_match_sets = MAX_PNO_LIST_COUNT;
9606
#endif
9607
#endif
9608
#endif
9609
9610
#if defined(CONFIG_PM) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
9611
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0))
9612
wiphy->wowlan = wowlan_stub;
9613
#else
9614
wiphy->wowlan = &wowlan_stub;
9615
#endif
9616
#endif
9617
9618
#if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
9619
wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
9620
#ifndef CONFIG_TDLS_DRIVER_SETUP
9621
wiphy->flags |= WIPHY_FLAG_TDLS_EXTERNAL_SETUP; /* Driver handles key exchange */
9622
wiphy->flags |= NL80211_ATTR_HT_CAPABILITY;
9623
#endif /* CONFIG_TDLS_DRIVER_SETUP */
9624
#endif /* CONFIG_TDLS */
9625
9626
if (regsty->power_mgnt != PS_MODE_ACTIVE)
9627
wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
9628
else
9629
wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
9630
9631
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
9632
/* wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM; */
9633
#endif
9634
9635
#ifdef CONFIG_RTW_MESH
9636
wiphy->flags |= 0
9637
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
9638
| WIPHY_FLAG_IBSS_RSN
9639
#endif
9640
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
9641
| WIPHY_FLAG_MESH_AUTH
9642
#endif
9643
;
9644
9645
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0))
9646
wiphy->features |= 0
9647
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0))
9648
| NL80211_FEATURE_USERSPACE_MPM
9649
#endif
9650
;
9651
#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) */
9652
#endif /* CONFIG_RTW_MESH */
9653
9654
#if (KERNEL_VERSION(3, 8, 0) <= LINUX_VERSION_CODE)
9655
wiphy->features |= NL80211_FEATURE_SAE;
9656
#endif
9657
}
9658
9659
#ifdef CONFIG_RFKILL_POLL
9660
void rtw_cfg80211_init_rfkill(struct wiphy *wiphy)
9661
{
9662
wiphy_rfkill_set_hw_state(wiphy, 0);
9663
wiphy_rfkill_start_polling(wiphy);
9664
}
9665
9666
void rtw_cfg80211_deinit_rfkill(struct wiphy *wiphy)
9667
{
9668
wiphy_rfkill_stop_polling(wiphy);
9669
}
9670
9671
static void cfg80211_rtw_rfkill_poll(struct wiphy *wiphy)
9672
{
9673
_adapter *padapter = NULL;
9674
bool blocked = _FALSE;
9675
u8 valid = 0;
9676
9677
padapter = wiphy_to_adapter(wiphy);
9678
9679
if (adapter_to_dvobj(padapter)->processing_dev_remove == _TRUE) {
9680
/*RTW_INFO("cfg80211_rtw_rfkill_poll: device is removed!\n");*/
9681
return;
9682
}
9683
9684
blocked = rtw_hal_rfkill_poll(padapter, &valid);
9685
/*RTW_INFO("cfg80211_rtw_rfkill_poll: valid=%d, blocked=%d\n",
9686
valid, blocked);*/
9687
9688
if (valid)
9689
wiphy_rfkill_set_hw_state(wiphy, blocked);
9690
}
9691
#endif
9692
9693
#if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
9694
9695
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) && (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
9696
#define SURVEY_INFO_TIME SURVEY_INFO_CHANNEL_TIME
9697
#define SURVEY_INFO_TIME_BUSY SURVEY_INFO_CHANNEL_TIME_BUSY
9698
#define SURVEY_INFO_TIME_EXT_BUSY SURVEY_INFO_CHANNEL_TIME_EXT_BUSY
9699
#define SURVEY_INFO_TIME_RX SURVEY_INFO_CHANNEL_TIME_RX
9700
#define SURVEY_INFO_TIME_TX SURVEY_INFO_CHANNEL_TIME_TX
9701
#endif
9702
9703
#ifdef CONFIG_FIND_BEST_CHANNEL
9704
static void rtw_cfg80211_set_survey_info_with_find_best_channel(struct wiphy *wiphy
9705
, struct net_device *netdev, int idx, struct survey_info *info)
9706
{
9707
_adapter *adapter = (_adapter *)rtw_netdev_priv(netdev);
9708
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
9709
RT_CHANNEL_INFO *ch_set = rfctl->channel_set;
9710
u8 ch_num = rfctl->max_chan_nums;
9711
u32 total_rx_cnt = 0;
9712
int i;
9713
9714
s8 noise = -50; /*channel noise in dBm. This and all following fields are optional */
9715
u64 time = 100; /*amount of time in ms the radio was turn on (on the channel)*/
9716
u64 time_busy = 0; /*amount of time the primary channel was sensed busy*/
9717
9718
info->filled = SURVEY_INFO_NOISE_DBM
9719
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
9720
| SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY
9721
#endif
9722
;
9723
9724
for (i = 0; i < ch_num; i++)
9725
total_rx_cnt += ch_set[i].rx_count;
9726
9727
time_busy = ch_set[idx].rx_count * time / total_rx_cnt;
9728
noise += ch_set[idx].rx_count * 50 / total_rx_cnt;
9729
9730
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
9731
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
9732
info->channel_time = time;
9733
info->channel_time_busy = time_busy;
9734
#else
9735
info->time = time;
9736
info->time_busy = time_busy;
9737
#endif
9738
#endif
9739
info->noise = noise;
9740
9741
/* reset if final channel is got */
9742
if (idx == ch_num - 1) {
9743
for (i = 0; i < ch_num; i++)
9744
ch_set[i].rx_count = 0;
9745
}
9746
}
9747
#endif /* CONFIG_FIND_BEST_CHANNEL */
9748
9749
#if defined(CONFIG_RTW_ACS) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
9750
static void rtw_cfg80211_set_survey_info_with_clm(PADAPTER padapter, int idx, struct survey_info *pinfo)
9751
{
9752
s8 noise = -50; /*channel noise in dBm. This and all following fields are optional */
9753
u64 time = SURVEY_TO; /*amount of time in ms the radio was turn on (on the channel)*/
9754
u64 time_busy = 0; /*amount of time the primary channel was sensed busy*/
9755
u8 chan = (u8)idx;
9756
9757
if ((idx < 0) || (pinfo == NULL))
9758
return;
9759
9760
pinfo->filled = SURVEY_INFO_NOISE_DBM
9761
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
9762
| SURVEY_INFO_TIME | SURVEY_INFO_TIME_BUSY
9763
#endif
9764
;
9765
9766
time_busy = rtw_acs_get_clm_ratio_by_ch_idx(padapter, chan);
9767
noise = rtw_noise_query_by_chan_idx(padapter, chan);
9768
/* RTW_INFO("%s: ch-idx:%d time=%llu(ms), time_busy=%llu(ms), noise=%d(dbm)\n", __func__, idx, time, time_busy, noise); */
9769
9770
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
9771
#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 0, 0))
9772
pinfo->channel_time = time;
9773
pinfo->channel_time_busy = time_busy;
9774
#else
9775
pinfo->time = time;
9776
pinfo->time_busy = time_busy;
9777
#endif
9778
#endif
9779
pinfo->noise = noise;
9780
}
9781
#endif
9782
9783
int rtw_hostapd_acs_dump_survey(struct wiphy *wiphy, struct net_device *netdev, int idx, struct survey_info *info)
9784
{
9785
PADAPTER padapter = (_adapter *)rtw_netdev_priv(netdev);
9786
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
9787
RT_CHANNEL_INFO *pch_set = rfctl->channel_set;
9788
u8 max_chan_nums = rfctl->max_chan_nums;
9789
u32 freq = 0;
9790
u8 ret = 0;
9791
u16 channel = 0;
9792
9793
if (!netdev || !info) {
9794
RTW_INFO("%s: invial parameters.\n", __func__);
9795
return -EINVAL;
9796
}
9797
9798
_rtw_memset(info, 0, sizeof(struct survey_info));
9799
if (padapter->bup == _FALSE) {
9800
RTW_INFO("%s: net device is down.\n", __func__);
9801
return -EIO;
9802
}
9803
9804
if (idx >= max_chan_nums)
9805
return -ENOENT;
9806
9807
channel = pch_set[idx].ChannelNum;
9808
freq = rtw_ch2freq(channel);
9809
info->channel = ieee80211_get_channel(wiphy, freq);
9810
/* RTW_INFO("%s: channel %d, freq %d\n", __func__, channel, freq); */
9811
9812
if (!info->channel)
9813
return -EINVAL;
9814
9815
if (info->channel->flags == IEEE80211_CHAN_DISABLED)
9816
return ret;
9817
9818
#ifdef CONFIG_FIND_BEST_CHANNEL
9819
rtw_cfg80211_set_survey_info_with_find_best_channel(wiphy, netdev, idx, info);
9820
#elif defined(CONFIG_RTW_ACS) && defined(CONFIG_BACKGROUND_NOISE_MONITOR)
9821
rtw_cfg80211_set_survey_info_with_clm(padapter, idx, info);
9822
#else
9823
RTW_ERR("%s: unknown acs operation!\n", __func__);
9824
#endif
9825
9826
return ret;
9827
}
9828
#endif /* defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33)) */
9829
9830
#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE)
9831
int cfg80211_rtw_external_auth(struct wiphy *wiphy, struct net_device *dev,
9832
struct cfg80211_external_auth_params *params)
9833
{
9834
PADAPTER padapter = (_adapter *)rtw_netdev_priv(dev);
9835
9836
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(dev));
9837
9838
rtw_cfg80211_external_auth_status(wiphy, dev,
9839
(struct rtw_external_auth_params *)params);
9840
9841
return 0;
9842
}
9843
#endif
9844
9845
void rtw_cfg80211_external_auth_status(struct wiphy *wiphy, struct net_device *dev,
9846
struct rtw_external_auth_params *params)
9847
{
9848
PADAPTER padapter = (_adapter *)rtw_netdev_priv(dev);
9849
struct security_priv *psecuritypriv = &padapter->securitypriv;
9850
struct sta_priv *pstapriv = &padapter->stapriv;
9851
struct sta_info *psta = NULL;
9852
u8 *buf = NULL;
9853
u32 len = 0;
9854
_irqL irqL;
9855
9856
RTW_INFO(FUNC_NDEV_FMT"\n", FUNC_NDEV_ARG(dev));
9857
9858
RTW_INFO("SAE: action: %u, status: %u\n", params->action, params->status);
9859
if (params->status == WLAN_STATUS_SUCCESS) {
9860
RTW_INFO("bssid: "MAC_FMT"\n", MAC_ARG(params->bssid));
9861
RTW_INFO("SSID: [%s]\n",
9862
((params->ssid.ssid_len == 0) ? "" : (char *)params->ssid.ssid));
9863
RTW_INFO("suite: 0x%08x\n", params->key_mgmt_suite);
9864
}
9865
9866
psta = rtw_get_stainfo(pstapriv, params->bssid);
9867
if (psta && (params->status == WLAN_STATUS_SUCCESS)) {
9868
/* AP mode */
9869
RTW_INFO("station match\n");
9870
9871
psta->state &= ~WIFI_FW_AUTH_NULL;
9872
psta->state |= WIFI_FW_AUTH_SUCCESS;
9873
psta->expire_to = padapter->stapriv.assoc_to;
9874
9875
/* ToDo: Kernel v5.1 pmkid is pointer */
9876
/* RTW_INFO_DUMP("PMKID:", params->pmkid, PMKID_LEN); */
9877
_rtw_set_pmksa(dev, params->bssid, params->pmkid);
9878
9879
_enter_critical_bh(&psta->lock, &irqL);
9880
if ((psta->auth_len != 0) && (psta->pauth_frame != NULL)) {
9881
buf = rtw_zmalloc(psta->auth_len);
9882
if (buf) {
9883
_rtw_memcpy(buf, psta->pauth_frame, psta->auth_len);
9884
len = psta->auth_len;
9885
}
9886
9887
rtw_mfree(psta->pauth_frame, psta->auth_len);
9888
psta->pauth_frame = NULL;
9889
psta->auth_len = 0;
9890
}
9891
_exit_critical_bh(&psta->lock, &irqL);
9892
9893
if (buf) {
9894
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9895
/* send the SAE auth Confirm */
9896
9897
rtw_ps_deny(padapter, PS_DENY_MGNT_TX);
9898
if (_SUCCESS == rtw_pwr_wakeup(padapter)) {
9899
rtw_mi_set_scan_deny(padapter, 1000);
9900
rtw_mi_scan_abort(padapter, _TRUE);
9901
9902
RTW_INFO("SAE: Tx auth Confirm\n");
9903
rtw_mgnt_tx_cmd(padapter, pmlmeext->cur_channel, 1, buf, len, 0, RTW_CMDF_DIRECTLY);
9904
9905
}
9906
rtw_ps_deny_cancel(padapter, PS_DENY_MGNT_TX);
9907
9908
rtw_mfree(buf, len);
9909
buf = NULL;
9910
len = 0;
9911
}
9912
} else {
9913
/* STA mode */
9914
psecuritypriv->extauth_status = params->status;
9915
}
9916
}
9917
9918
static struct cfg80211_ops rtw_cfg80211_ops = {
9919
.change_virtual_intf = cfg80211_rtw_change_iface,
9920
.add_key = cfg80211_rtw_add_key,
9921
.get_key = cfg80211_rtw_get_key,
9922
.del_key = cfg80211_rtw_del_key,
9923
.set_default_key = cfg80211_rtw_set_default_key,
9924
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 30))
9925
.set_default_mgmt_key = cfg80211_rtw_set_default_mgmt_key,
9926
#endif
9927
#if defined(CONFIG_GTK_OL) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 1, 0))
9928
.set_rekey_data = cfg80211_rtw_set_rekey_data,
9929
#endif /*CONFIG_GTK_OL*/
9930
.get_station = cfg80211_rtw_get_station,
9931
.scan = cfg80211_rtw_scan,
9932
.set_wiphy_params = cfg80211_rtw_set_wiphy_params,
9933
.connect = cfg80211_rtw_connect,
9934
.disconnect = cfg80211_rtw_disconnect,
9935
.join_ibss = cfg80211_rtw_join_ibss,
9936
.leave_ibss = cfg80211_rtw_leave_ibss,
9937
.set_tx_power = cfg80211_rtw_set_txpower,
9938
.get_tx_power = cfg80211_rtw_get_txpower,
9939
.set_power_mgmt = cfg80211_rtw_set_power_mgmt,
9940
.set_pmksa = cfg80211_rtw_set_pmksa,
9941
.del_pmksa = cfg80211_rtw_del_pmksa,
9942
.flush_pmksa = cfg80211_rtw_flush_pmksa,
9943
9944
#ifdef CONFIG_AP_MODE
9945
.add_virtual_intf = cfg80211_rtw_add_virtual_intf,
9946
.del_virtual_intf = cfg80211_rtw_del_virtual_intf,
9947
9948
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 4, 0)) && !defined(COMPAT_KERNEL_RELEASE)
9949
.add_beacon = cfg80211_rtw_add_beacon,
9950
.set_beacon = cfg80211_rtw_set_beacon,
9951
.del_beacon = cfg80211_rtw_del_beacon,
9952
#else
9953
.start_ap = cfg80211_rtw_start_ap,
9954
.change_beacon = cfg80211_rtw_change_beacon,
9955
.stop_ap = cfg80211_rtw_stop_ap,
9956
#endif
9957
9958
#if CONFIG_RTW_MACADDR_ACL && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 9, 0))
9959
.set_mac_acl = cfg80211_rtw_set_mac_acl,
9960
#endif
9961
9962
.add_station = cfg80211_rtw_add_station,
9963
.del_station = cfg80211_rtw_del_station,
9964
.change_station = cfg80211_rtw_change_station,
9965
.dump_station = cfg80211_rtw_dump_station,
9966
.change_bss = cfg80211_rtw_change_bss,
9967
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29))
9968
.set_txq_params = cfg80211_rtw_set_txq_params,
9969
#endif
9970
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
9971
.set_channel = cfg80211_rtw_set_channel,
9972
#endif
9973
/* .auth = cfg80211_rtw_auth, */
9974
/* .assoc = cfg80211_rtw_assoc, */
9975
#endif /* CONFIG_AP_MODE */
9976
9977
#if defined(CONFIG_RTW_MESH) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 38))
9978
.get_mesh_config = cfg80211_rtw_get_mesh_config,
9979
.update_mesh_config = cfg80211_rtw_update_mesh_config,
9980
.join_mesh = cfg80211_rtw_join_mesh,
9981
.leave_mesh = cfg80211_rtw_leave_mesh,
9982
.add_mpath = cfg80211_rtw_add_mpath,
9983
.del_mpath = cfg80211_rtw_del_mpath,
9984
.change_mpath = cfg80211_rtw_change_mpath,
9985
.get_mpath = cfg80211_rtw_get_mpath,
9986
.dump_mpath = cfg80211_rtw_dump_mpath,
9987
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
9988
.get_mpp = cfg80211_rtw_get_mpp,
9989
.dump_mpp = cfg80211_rtw_dump_mpp,
9990
#endif
9991
#endif
9992
9993
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 6, 0))
9994
.set_monitor_channel = cfg80211_rtw_set_monitor_channel,
9995
#endif
9996
9997
#ifdef CONFIG_P2P
9998
.remain_on_channel = cfg80211_rtw_remain_on_channel,
9999
.cancel_remain_on_channel = cfg80211_rtw_cancel_remain_on_channel,
10000
#if defined(RTW_DEDICATED_P2P_DEVICE)
10001
.start_p2p_device = cfg80211_rtw_start_p2p_device,
10002
.stop_p2p_device = cfg80211_rtw_stop_p2p_device,
10003
#endif
10004
#endif /* CONFIG_P2P */
10005
10006
#ifdef CONFIG_RTW_80211R
10007
.update_ft_ies = cfg80211_rtw_update_ft_ies,
10008
#endif
10009
10010
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
10011
.mgmt_tx = cfg80211_rtw_mgmt_tx,
10012
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0))
10013
.update_mgmt_frame_registrations = cfg80211_rtw_update_mgmt_frame_register,
10014
#else
10015
.mgmt_frame_register = cfg80211_rtw_mgmt_frame_register,
10016
#endif
10017
#elif (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34) && LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
10018
.action = cfg80211_rtw_mgmt_tx,
10019
#endif
10020
10021
#if defined(CONFIG_TDLS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 2, 0))
10022
.tdls_mgmt = cfg80211_rtw_tdls_mgmt,
10023
.tdls_oper = cfg80211_rtw_tdls_oper,
10024
#endif /* CONFIG_TDLS */
10025
10026
#if defined(CONFIG_PNO_SUPPORT) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0))
10027
.sched_scan_start = cfg80211_rtw_sched_scan_start,
10028
.sched_scan_stop = cfg80211_rtw_sched_scan_stop,
10029
.suspend = cfg80211_rtw_suspend,
10030
.resume = cfg80211_rtw_resume,
10031
#endif /* CONFIG_PNO_SUPPORT */
10032
#ifdef CONFIG_RFKILL_POLL
10033
.rfkill_poll = cfg80211_rtw_rfkill_poll,
10034
#endif
10035
#if defined(CONFIG_RTW_HOSTAPD_ACS) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 33))
10036
.dump_survey = rtw_hostapd_acs_dump_survey,
10037
#endif
10038
#if (KERNEL_VERSION(4, 17, 0) <= LINUX_VERSION_CODE)
10039
.external_auth = cfg80211_rtw_external_auth,
10040
#endif
10041
};
10042
10043
struct wiphy *rtw_wiphy_alloc(_adapter *padapter, struct device *dev)
10044
{
10045
struct wiphy *wiphy;
10046
struct rtw_wiphy_data *wiphy_data;
10047
10048
/* wiphy */
10049
wiphy = wiphy_new(&rtw_cfg80211_ops, sizeof(struct rtw_wiphy_data));
10050
if (!wiphy) {
10051
RTW_INFO("Couldn't allocate wiphy device\n");
10052
goto exit;
10053
}
10054
set_wiphy_dev(wiphy, dev);
10055
10056
/* wiphy_data */
10057
wiphy_data = rtw_wiphy_priv(wiphy);
10058
wiphy_data->dvobj = adapter_to_dvobj(padapter);
10059
#ifndef RTW_SINGLE_WIPHY
10060
wiphy_data->adapter = padapter;
10061
#endif
10062
10063
rtw_cfg80211_preinit_wiphy(padapter, wiphy);
10064
10065
RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10066
10067
exit:
10068
return wiphy;
10069
}
10070
10071
void rtw_wiphy_free(struct wiphy *wiphy)
10072
{
10073
if (!wiphy)
10074
return;
10075
10076
RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10077
10078
if (wiphy->bands[NL80211_BAND_2GHZ]) {
10079
rtw_spt_band_free(wiphy->bands[NL80211_BAND_2GHZ]);
10080
wiphy->bands[NL80211_BAND_2GHZ] = NULL;
10081
}
10082
if (wiphy->bands[NL80211_BAND_5GHZ]) {
10083
rtw_spt_band_free(wiphy->bands[NL80211_BAND_5GHZ]);
10084
wiphy->bands[NL80211_BAND_5GHZ] = NULL;
10085
}
10086
10087
wiphy_free(wiphy);
10088
}
10089
10090
int rtw_wiphy_register(struct wiphy *wiphy)
10091
{
10092
RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10093
10094
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
10095
rtw_cfgvendor_attach(wiphy);
10096
#endif
10097
10098
rtw_regd_init(wiphy);
10099
10100
return wiphy_register(wiphy);
10101
}
10102
10103
void rtw_wiphy_unregister(struct wiphy *wiphy)
10104
{
10105
RTW_INFO(FUNC_WIPHY_FMT"\n", FUNC_WIPHY_ARG(wiphy));
10106
10107
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)) || defined(RTW_VENDOR_EXT_SUPPORT)
10108
rtw_cfgvendor_detach(wiphy);
10109
#endif
10110
10111
#if defined(RTW_DEDICATED_P2P_DEVICE)
10112
rtw_pd_iface_free(wiphy);
10113
#endif
10114
10115
return wiphy_unregister(wiphy);
10116
}
10117
10118
int rtw_wdev_alloc(_adapter *padapter, struct wiphy *wiphy)
10119
{
10120
int ret = 0;
10121
struct net_device *pnetdev = padapter->pnetdev;
10122
struct wireless_dev *wdev;
10123
struct rtw_wdev_priv *pwdev_priv;
10124
10125
RTW_INFO("%s(padapter=%p)\n", __func__, padapter);
10126
10127
/* wdev */
10128
wdev = (struct wireless_dev *)rtw_zmalloc(sizeof(struct wireless_dev));
10129
if (!wdev) {
10130
RTW_INFO("Couldn't allocate wireless device\n");
10131
ret = -ENOMEM;
10132
goto exit;
10133
}
10134
wdev->wiphy = wiphy;
10135
wdev->netdev = pnetdev;
10136
wdev->iftype = NL80211_IFTYPE_STATION;
10137
padapter->rtw_wdev = wdev;
10138
pnetdev->ieee80211_ptr = wdev;
10139
10140
/* init pwdev_priv */
10141
pwdev_priv = adapter_wdev_data(padapter);
10142
pwdev_priv->rtw_wdev = wdev;
10143
pwdev_priv->pmon_ndev = NULL;
10144
pwdev_priv->ifname_mon[0] = '\0';
10145
pwdev_priv->padapter = padapter;
10146
pwdev_priv->scan_request = NULL;
10147
_rtw_spinlock_init(&pwdev_priv->scan_req_lock);
10148
pwdev_priv->connect_req = NULL;
10149
_rtw_spinlock_init(&pwdev_priv->connect_req_lock);
10150
10151
pwdev_priv->p2p_enabled = _FALSE;
10152
pwdev_priv->probe_resp_ie_update_time = rtw_get_current_time();
10153
pwdev_priv->provdisc_req_issued = _FALSE;
10154
rtw_wdev_invit_info_init(&pwdev_priv->invit_info);
10155
rtw_wdev_nego_info_init(&pwdev_priv->nego_info);
10156
10157
pwdev_priv->bandroid_scan = _FALSE;
10158
10159
if (padapter->registrypriv.power_mgnt != PS_MODE_ACTIVE)
10160
pwdev_priv->power_mgmt = _TRUE;
10161
else
10162
pwdev_priv->power_mgmt = _FALSE;
10163
10164
_rtw_mutex_init(&pwdev_priv->roch_mutex);
10165
10166
#ifdef CONFIG_CONCURRENT_MODE
10167
ATOMIC_SET(&pwdev_priv->switch_ch_to, 1);
10168
#endif
10169
10170
#ifdef CONFIG_RTW_CFGVEDNOR_RSSIMONITOR
10171
pwdev_priv->rssi_monitor_enable = 0;
10172
pwdev_priv->rssi_monitor_max = 0;
10173
pwdev_priv->rssi_monitor_min = 0;
10174
#endif
10175
10176
10177
exit:
10178
return ret;
10179
}
10180
10181
void rtw_wdev_free(struct wireless_dev *wdev)
10182
{
10183
if (!wdev)
10184
return;
10185
10186
RTW_INFO("%s(wdev=%p)\n", __func__, wdev);
10187
10188
if (wdev_to_ndev(wdev)) {
10189
_adapter *adapter = (_adapter *)rtw_netdev_priv(wdev_to_ndev(wdev));
10190
struct rtw_wdev_priv *wdev_priv = adapter_wdev_data(adapter);
10191
_irqL irqL;
10192
10193
_rtw_spinlock_free(&wdev_priv->scan_req_lock);
10194
10195
_enter_critical_bh(&wdev_priv->connect_req_lock, &irqL);
10196
rtw_wdev_free_connect_req(wdev_priv);
10197
_exit_critical_bh(&wdev_priv->connect_req_lock, &irqL);
10198
_rtw_spinlock_free(&wdev_priv->connect_req_lock);
10199
10200
_rtw_mutex_free(&wdev_priv->roch_mutex);
10201
}
10202
10203
rtw_mfree((u8 *)wdev, sizeof(struct wireless_dev));
10204
}
10205
10206
void rtw_wdev_unregister(struct wireless_dev *wdev)
10207
{
10208
struct net_device *ndev;
10209
_adapter *adapter;
10210
struct rtw_wdev_priv *pwdev_priv;
10211
10212
if (!wdev)
10213
return;
10214
10215
RTW_INFO("%s(wdev=%p)\n", __func__, wdev);
10216
10217
ndev = wdev_to_ndev(wdev);
10218
if (!ndev)
10219
return;
10220
10221
adapter = (_adapter *)rtw_netdev_priv(ndev);
10222
pwdev_priv = adapter_wdev_data(adapter);
10223
10224
rtw_cfg80211_indicate_scan_done(adapter, _TRUE);
10225
10226
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 11, 0)) || defined(COMPAT_KERNEL_RELEASE)
10227
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 19, 2))
10228
if (wdev->links[0].client.current_bss) {
10229
#else
10230
if (wdev->current_bss) {
10231
#endif
10232
RTW_INFO(FUNC_ADPT_FMT" clear current_bss by cfg80211_disconnected\n", FUNC_ADPT_ARG(adapter));
10233
rtw_cfg80211_indicate_disconnect(adapter, 0, 1);
10234
}
10235
#endif
10236
10237
if (pwdev_priv->pmon_ndev) {
10238
RTW_INFO("%s, unregister monitor interface\n", __func__);
10239
unregister_netdev(pwdev_priv->pmon_ndev);
10240
}
10241
}
10242
10243
int rtw_cfg80211_ndev_res_alloc(_adapter *adapter)
10244
{
10245
int ret = _FAIL;
10246
10247
#if !defined(RTW_SINGLE_WIPHY)
10248
struct wiphy *wiphy;
10249
struct device *dev = dvobj_to_dev(adapter_to_dvobj(adapter));
10250
10251
wiphy = rtw_wiphy_alloc(adapter, dev);
10252
if (wiphy == NULL)
10253
goto exit;
10254
10255
adapter->wiphy = wiphy;
10256
#endif
10257
10258
if (rtw_wdev_alloc(adapter, adapter_to_wiphy(adapter)) == 0)
10259
ret = _SUCCESS;
10260
10261
#if !defined(RTW_SINGLE_WIPHY)
10262
if (ret != _SUCCESS) {
10263
rtw_wiphy_free(wiphy);
10264
adapter->wiphy = NULL;
10265
}
10266
#endif
10267
10268
exit:
10269
return ret;
10270
}
10271
10272
void rtw_cfg80211_ndev_res_free(_adapter *adapter)
10273
{
10274
rtw_wdev_free(adapter->rtw_wdev);
10275
adapter->rtw_wdev = NULL;
10276
#if !defined(RTW_SINGLE_WIPHY)
10277
rtw_wiphy_free(adapter_to_wiphy(adapter));
10278
adapter->wiphy = NULL;
10279
#endif
10280
}
10281
10282
int rtw_cfg80211_ndev_res_register(_adapter *adapter)
10283
{
10284
int ret = _FAIL;
10285
10286
#if !defined(RTW_SINGLE_WIPHY)
10287
if (rtw_wiphy_register(adapter_to_wiphy(adapter)) < 0) {
10288
RTW_INFO("%s rtw_wiphy_register fail for if%d\n", __func__, (adapter->iface_id + 1));
10289
goto exit;
10290
}
10291
10292
#ifdef CONFIG_RFKILL_POLL
10293
rtw_cfg80211_init_rfkill(adapter_to_wiphy(adapter));
10294
#endif
10295
#endif
10296
10297
ret = _SUCCESS;
10298
10299
exit:
10300
return ret;
10301
}
10302
10303
void rtw_cfg80211_ndev_res_unregister(_adapter *adapter)
10304
{
10305
rtw_wdev_unregister(adapter->rtw_wdev);
10306
}
10307
10308
int rtw_cfg80211_dev_res_alloc(struct dvobj_priv *dvobj)
10309
{
10310
int ret = _FAIL;
10311
10312
#if defined(RTW_SINGLE_WIPHY)
10313
struct wiphy *wiphy;
10314
struct device *dev = dvobj_to_dev(dvobj);
10315
10316
wiphy = rtw_wiphy_alloc(dvobj_get_primary_adapter(dvobj), dev);
10317
if (wiphy == NULL)
10318
return ret;
10319
10320
dvobj->wiphy = wiphy;
10321
#endif
10322
10323
ret = _SUCCESS;
10324
return ret;
10325
}
10326
10327
void rtw_cfg80211_dev_res_free(struct dvobj_priv *dvobj)
10328
{
10329
#if defined(RTW_SINGLE_WIPHY)
10330
rtw_wiphy_free(dvobj_to_wiphy(dvobj));
10331
dvobj->wiphy = NULL;
10332
#endif
10333
}
10334
10335
int rtw_cfg80211_dev_res_register(struct dvobj_priv *dvobj)
10336
{
10337
int ret = _FAIL;
10338
10339
#if defined(RTW_SINGLE_WIPHY)
10340
if (rtw_wiphy_register(dvobj_to_wiphy(dvobj)) != 0)
10341
return ret;
10342
10343
#ifdef CONFIG_RFKILL_POLL
10344
rtw_cfg80211_init_rfkill(dvobj_to_wiphy(dvobj));
10345
#endif
10346
#endif
10347
10348
ret = _SUCCESS;
10349
10350
return ret;
10351
}
10352
10353
void rtw_cfg80211_dev_res_unregister(struct dvobj_priv *dvobj)
10354
{
10355
#if defined(RTW_SINGLE_WIPHY)
10356
#ifdef CONFIG_RFKILL_POLL
10357
rtw_cfg80211_deinit_rfkill(dvobj_to_wiphy(dvobj));
10358
#endif
10359
rtw_wiphy_unregister(dvobj_to_wiphy(dvobj));
10360
#endif
10361
}
10362
10363
#endif /* CONFIG_IOCTL_CFG80211 */
10364
10365