Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_mlme_ext.c
1307 views
1
/******************************************************************************
2
*
3
* Copyright(c) 2007 - 2019 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 _RTW_MLME_EXT_C_
16
17
#include <drv_types.h>
18
#ifdef CONFIG_IOCTL_CFG80211
19
#include <rtw_wifi_regd.h>
20
#endif /* CONFIG_IOCTL_CFG80211 */
21
#include <hal_data.h>
22
23
24
struct mlme_handler mlme_sta_tbl[] = {
25
{WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
26
{WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
27
{WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
28
{WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
29
{WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
30
{WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
31
32
/*----------------------------------------------------------
33
below 2 are reserved
34
-----------------------------------------------------------*/
35
{0, "DoReserved", &DoReserved},
36
{0, "DoReserved", &DoReserved},
37
{WIFI_BEACON, "OnBeacon", &OnBeacon},
38
{WIFI_ATIM, "OnATIM", &OnAtim},
39
{WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
40
{WIFI_AUTH, "OnAuth", &OnAuthClient},
41
{WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
42
{WIFI_ACTION, "OnAction", &OnAction},
43
{WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
44
};
45
46
#ifdef _CONFIG_NATIVEAP_MLME_
47
struct mlme_handler mlme_ap_tbl[] = {
48
{WIFI_ASSOCREQ, "OnAssocReq", &OnAssocReq},
49
{WIFI_ASSOCRSP, "OnAssocRsp", &OnAssocRsp},
50
{WIFI_REASSOCREQ, "OnReAssocReq", &OnAssocReq},
51
{WIFI_REASSOCRSP, "OnReAssocRsp", &OnAssocRsp},
52
{WIFI_PROBEREQ, "OnProbeReq", &OnProbeReq},
53
{WIFI_PROBERSP, "OnProbeRsp", &OnProbeRsp},
54
55
/*----------------------------------------------------------
56
below 2 are reserved
57
-----------------------------------------------------------*/
58
{0, "DoReserved", &DoReserved},
59
{0, "DoReserved", &DoReserved},
60
{WIFI_BEACON, "OnBeacon", &OnBeacon},
61
{WIFI_ATIM, "OnATIM", &OnAtim},
62
{WIFI_DISASSOC, "OnDisassoc", &OnDisassoc},
63
{WIFI_AUTH, "OnAuth", &OnAuth},
64
{WIFI_DEAUTH, "OnDeAuth", &OnDeAuth},
65
{WIFI_ACTION, "OnAction", &OnAction},
66
{WIFI_ACTION_NOACK, "OnActionNoAck", &OnAction},
67
};
68
#endif
69
70
struct action_handler OnAction_tbl[] = {
71
{RTW_WLAN_CATEGORY_SPECTRUM_MGMT, "ACTION_SPECTRUM_MGMT", on_action_spct},
72
{RTW_WLAN_CATEGORY_QOS, "ACTION_QOS", &OnAction_qos},
73
{RTW_WLAN_CATEGORY_DLS, "ACTION_DLS", &OnAction_dls},
74
{RTW_WLAN_CATEGORY_BACK, "ACTION_BACK", &OnAction_back},
75
{RTW_WLAN_CATEGORY_PUBLIC, "ACTION_PUBLIC", on_action_public},
76
{RTW_WLAN_CATEGORY_RADIO_MEAS, "ACTION_RADIO_MEAS", &on_action_rm},
77
{RTW_WLAN_CATEGORY_FT, "ACTION_FT", &OnAction_ft},
78
{RTW_WLAN_CATEGORY_HT, "ACTION_HT", &OnAction_ht},
79
#ifdef CONFIG_IEEE80211W
80
{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &OnAction_sa_query},
81
#else
82
{RTW_WLAN_CATEGORY_SA_QUERY, "ACTION_SA_QUERY", &DoReserved},
83
#endif /* CONFIG_IEEE80211W */
84
#ifdef CONFIG_RTW_WNM
85
{RTW_WLAN_CATEGORY_WNM, "ACTION_WNM", &on_action_wnm},
86
#endif
87
{RTW_WLAN_CATEGORY_UNPROTECTED_WNM, "ACTION_UNPROTECTED_WNM", &DoReserved},
88
#ifdef CONFIG_RTW_MESH
89
{RTW_WLAN_CATEGORY_MESH, "ACTION_MESH", &on_action_mesh},
90
{RTW_WLAN_CATEGORY_SELF_PROTECTED, "ACTION_SELF_PROTECTED", &on_action_self_protected},
91
#endif
92
{RTW_WLAN_CATEGORY_WMM, "ACTION_WMM", &OnAction_wmm},
93
{RTW_WLAN_CATEGORY_VHT, "ACTION_VHT", &OnAction_vht},
94
{RTW_WLAN_CATEGORY_P2P, "ACTION_P2P", &OnAction_p2p},
95
};
96
97
98
u8 null_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0};
99
100
/**************************************************
101
OUI definitions for the vendor specific IE
102
***************************************************/
103
unsigned char RTW_WPA_OUI[] = {0x00, 0x50, 0xf2, 0x01};
104
unsigned char WMM_OUI[] = {0x00, 0x50, 0xf2, 0x02};
105
unsigned char WPS_OUI[] = {0x00, 0x50, 0xf2, 0x04};
106
unsigned char P2P_OUI[] = {0x50, 0x6F, 0x9A, 0x09};
107
unsigned char WFD_OUI[] = {0x50, 0x6F, 0x9A, 0x0A};
108
109
unsigned char WMM_INFO_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x00, 0x01};
110
unsigned char WMM_PARA_OUI[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
111
112
unsigned char WPA_TKIP_CIPHER[4] = {0x00, 0x50, 0xf2, 0x02};
113
unsigned char RSN_TKIP_CIPHER[4] = {0x00, 0x0f, 0xac, 0x02};
114
115
extern unsigned char REALTEK_96B_IE[];
116
117
static void init_channel_list(_adapter *padapter, RT_CHANNEL_INFO *channel_set
118
, struct p2p_channels *channel_list)
119
{
120
struct registry_priv *regsty = adapter_to_regsty(padapter);
121
122
struct p2p_oper_class_map op_class[] = {
123
{ IEEE80211G, 81, 1, 13, 1, BW20 },
124
{ IEEE80211G, 82, 14, 14, 1, BW20 },
125
#if 0 /* Do not enable HT40 on 2 GHz */
126
{ IEEE80211G, 83, 1, 9, 1, BW40PLUS },
127
{ IEEE80211G, 84, 5, 13, 1, BW40MINUS },
128
#endif
129
{ IEEE80211A, 115, 36, 48, 4, BW20 },
130
{ IEEE80211A, 116, 36, 44, 8, BW40PLUS },
131
{ IEEE80211A, 117, 40, 48, 8, BW40MINUS },
132
{ IEEE80211A, 124, 149, 161, 4, BW20 },
133
{ IEEE80211A, 125, 149, 169, 4, BW20 },
134
{ IEEE80211A, 126, 149, 157, 8, BW40PLUS },
135
{ IEEE80211A, 127, 153, 161, 8, BW40MINUS },
136
{ -1, 0, 0, 0, 0, BW20 }
137
};
138
139
int cla, op;
140
141
cla = 0;
142
143
for (op = 0; op_class[op].op_class; op++) {
144
u8 ch;
145
struct p2p_oper_class_map *o = &op_class[op];
146
struct p2p_reg_class *reg = NULL;
147
148
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
149
if (rtw_chset_search_ch(channel_set, ch) == -1)
150
continue;
151
#if defined(CONFIG_80211N_HT) || defined(CONFIG_80211AC_VHT)
152
if ((padapter->registrypriv.ht_enable == 0) && (o->inc == 8))
153
continue;
154
155
if ((REGSTY_IS_BW_5G_SUPPORT(regsty, CHANNEL_WIDTH_40)) &&
156
((o->bw == BW40MINUS) || (o->bw == BW40PLUS)))
157
continue;
158
#endif
159
if (reg == NULL) {
160
reg = &channel_list->reg_class[cla];
161
cla++;
162
reg->reg_class = o->op_class;
163
reg->channels = 0;
164
}
165
reg->channel[reg->channels] = ch;
166
reg->channels++;
167
}
168
}
169
channel_list->reg_classes = cla;
170
171
}
172
173
#if CONFIG_TXPWR_LIMIT
174
void rtw_txpwr_init_regd(struct rf_ctl_t *rfctl)
175
{
176
u8 regd;
177
struct regd_exc_ent *exc;
178
struct txpwr_lmt_ent *ent;
179
_irqL irqL;
180
181
_enter_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
182
183
rfctl->regd_name = NULL;
184
185
if (rfctl->txpwr_regd_num == 0) {
186
RTW_PRINT("there is no any txpwr_regd\n");
187
goto release_lock;
188
}
189
190
/* search from exception mapping */
191
exc = _rtw_regd_exc_search(rfctl
192
, rfctl->country_ent ? rfctl->country_ent->alpha2 : NULL
193
, rfctl->ChannelPlan);
194
if (exc) {
195
u8 has_country = (exc->country[0] == '\0' && exc->country[1] == '\0') ? 0 : 1;
196
197
if (strcmp(exc->regd_name, regd_str(TXPWR_LMT_NONE)) == 0)
198
rfctl->regd_name = regd_str(TXPWR_LMT_NONE);
199
else if (strcmp(exc->regd_name, regd_str(TXPWR_LMT_WW)) == 0)
200
rfctl->regd_name = regd_str(TXPWR_LMT_WW);
201
else {
202
ent = _rtw_txpwr_lmt_get_by_name(rfctl, exc->regd_name);
203
if (ent)
204
rfctl->regd_name = ent->regd_name;
205
}
206
207
RTW_PRINT("exception mapping country:%c%c domain:0x%02x to%s regd_name:%s\n"
208
, has_country ? exc->country[0] : '0'
209
, has_country ? exc->country[1] : '0'
210
, exc->domain
211
, rfctl->regd_name ? "" : " unknown"
212
, exc->regd_name
213
);
214
if (rfctl->regd_name)
215
goto release_lock;
216
}
217
218
/* follow default channel plan mapping */
219
regd = rtw_chplan_get_default_regd(rfctl->ChannelPlan);
220
if (regd == TXPWR_LMT_NONE)
221
rfctl->regd_name = regd_str(TXPWR_LMT_NONE);
222
else if (regd == TXPWR_LMT_WW)
223
rfctl->regd_name = regd_str(TXPWR_LMT_WW);
224
else {
225
ent = _rtw_txpwr_lmt_get_by_name(rfctl, regd_str(regd));
226
if (ent)
227
rfctl->regd_name = ent->regd_name;
228
}
229
230
RTW_PRINT("default mapping domain:0x%02x to%s regd_name:%s\n"
231
, rfctl->ChannelPlan
232
, rfctl->regd_name ? "" : " unknown"
233
, regd_str(regd)
234
);
235
if (rfctl->regd_name)
236
goto release_lock;
237
238
switch (regd) {
239
/*
240
* To support older chips without new predefined regd:
241
* - use FCC if IC or CHILE or MEXICO not found
242
* - use ETSI if KCC or ACMA not found
243
*/
244
case TXPWR_LMT_IC:
245
case TXPWR_LMT_KCC:
246
case TXPWR_LMT_ACMA:
247
case TXPWR_LMT_CHILE:
248
case TXPWR_LMT_MEXICO:
249
if (regd == TXPWR_LMT_IC || regd == TXPWR_LMT_CHILE || regd == TXPWR_LMT_MEXICO)
250
regd = TXPWR_LMT_FCC;
251
else if (regd == TXPWR_LMT_KCC || regd == TXPWR_LMT_ACMA)
252
regd = TXPWR_LMT_ETSI;
253
ent = _rtw_txpwr_lmt_get_by_name(rfctl, regd_str(regd));
254
if (ent)
255
rfctl->regd_name = ent->regd_name;
256
RTW_PRINT("alternate regd_name:%s %s\n"
257
, regd_str(regd)
258
, rfctl->regd_name ? "is used" : "not found"
259
);
260
if (rfctl->regd_name)
261
break;
262
/* fall through */
263
default:
264
rfctl->regd_name = regd_str(TXPWR_LMT_WW);
265
RTW_PRINT("assign %s for default case\n", regd_str(TXPWR_LMT_WW));
266
break;
267
};
268
269
release_lock:
270
_exit_critical_mutex(&rfctl->txpwr_lmt_mutex, &irqL);
271
}
272
#endif /* CONFIG_TXPWR_LIMIT */
273
274
void rtw_rfctl_init(_adapter *adapter)
275
{
276
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
277
278
rfctl->max_chan_nums = init_channel_set(adapter, rfctl->ChannelPlan, rfctl->channel_set);
279
init_channel_list(adapter, rfctl->channel_set, &rfctl->channel_list);
280
281
_rtw_mutex_init(&rfctl->offch_mutex);
282
283
#if CONFIG_TXPWR_LIMIT
284
_rtw_mutex_init(&rfctl->txpwr_lmt_mutex);
285
_rtw_init_listhead(&rfctl->reg_exc_list);
286
_rtw_init_listhead(&rfctl->txpwr_lmt_list);
287
#endif
288
289
rfctl->ch_sel_same_band_prefer = 1;
290
291
#ifdef CONFIG_DFS_MASTER
292
rfctl->cac_start_time = rfctl->cac_end_time = RTW_CAC_STOPPED;
293
rtw_init_timer(&(rfctl->radar_detect_timer), adapter, rtw_dfs_rd_timer_hdl, rfctl);
294
#endif
295
#ifdef CONFIG_DFS_SLAVE_WITH_RADAR_DETECT
296
rfctl->dfs_slave_with_rd = 1;
297
#endif
298
}
299
300
void rtw_rfctl_deinit(_adapter *adapter)
301
{
302
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
303
304
_rtw_mutex_free(&rfctl->offch_mutex);
305
306
#if CONFIG_TXPWR_LIMIT
307
rtw_regd_exc_list_free(rfctl);
308
rtw_txpwr_lmt_list_free(rfctl);
309
_rtw_mutex_free(&rfctl->txpwr_lmt_mutex);
310
#endif
311
}
312
313
#ifdef CONFIG_DFS_MASTER
314
/*
315
* called in rtw_dfs_rd_enable()
316
* assume the request channel coverage is DFS range
317
* base on the current status and the request channel coverage to check if need to reset complete CAC time
318
*/
319
bool rtw_is_cac_reset_needed(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
320
{
321
bool needed = _FALSE;
322
u32 cur_hi, cur_lo, hi, lo;
323
324
if (rfctl->radar_detected == 1) {
325
needed = _TRUE;
326
goto exit;
327
}
328
329
if (rfctl->radar_detect_ch == 0) {
330
needed = _TRUE;
331
goto exit;
332
}
333
334
if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
335
RTW_ERR("request detection range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
336
rtw_warn_on(1);
337
}
338
339
if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
340
RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
341
rtw_warn_on(1);
342
}
343
344
if (hi <= lo || cur_hi <= cur_lo) {
345
RTW_ERR("hi:%u, lo:%u, cur_hi:%u, cur_lo:%u\n", hi, lo, cur_hi, cur_lo);
346
rtw_warn_on(1);
347
}
348
349
if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo)) {
350
/* request is in current detect range */
351
goto exit;
352
}
353
354
/* check if request channel coverage has new range and the new range is in DFS range */
355
if (!rtw_is_range_overlap(hi, lo, cur_hi, cur_lo)) {
356
/* request has no overlap with current */
357
needed = _TRUE;
358
} else if (rtw_is_range_a_in_b(cur_hi, cur_lo, hi, lo)) {
359
/* request is supper set of current */
360
if ((hi != cur_hi && rtw_is_dfs_range(hi, cur_hi)) || (lo != cur_lo && rtw_is_dfs_range(cur_lo, lo)))
361
needed = _TRUE;
362
} else {
363
/* request is not supper set of current, but has overlap */
364
if ((lo < cur_lo && rtw_is_dfs_range(cur_lo, lo)) || (hi > cur_hi && rtw_is_dfs_range(hi, cur_hi)))
365
needed = _TRUE;
366
}
367
368
exit:
369
return needed;
370
}
371
372
bool _rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
373
{
374
bool ret = _FALSE;
375
u32 hi = 0, lo = 0;
376
u32 r_hi = 0, r_lo = 0;
377
int i;
378
379
if (rfctl->radar_detect_by_others)
380
goto exit;
381
382
if (rfctl->radar_detect_ch == 0)
383
goto exit;
384
385
if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
386
rtw_warn_on(1);
387
goto exit;
388
}
389
390
if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch
391
, rfctl->radar_detect_bw, rfctl->radar_detect_offset
392
, &r_hi, &r_lo) == _FALSE) {
393
rtw_warn_on(1);
394
goto exit;
395
}
396
397
if (rtw_is_range_overlap(hi, lo, r_hi, r_lo))
398
ret = _TRUE;
399
400
exit:
401
return ret;
402
}
403
404
bool rtw_rfctl_overlap_radar_detect_ch(struct rf_ctl_t *rfctl)
405
{
406
return _rtw_rfctl_overlap_radar_detect_ch(rfctl
407
, rfctl_to_dvobj(rfctl)->oper_channel
408
, rfctl_to_dvobj(rfctl)->oper_bwmode
409
, rfctl_to_dvobj(rfctl)->oper_ch_offset);
410
}
411
412
bool rtw_rfctl_is_tx_blocked_by_ch_waiting(struct rf_ctl_t *rfctl)
413
{
414
return rtw_rfctl_overlap_radar_detect_ch(rfctl) && IS_CH_WAITING(rfctl);
415
}
416
417
bool rtw_chset_is_chbw_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
418
{
419
bool ret = _FALSE;
420
u32 hi = 0, lo = 0;
421
int i;
422
423
if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
424
goto exit;
425
426
for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
427
if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
428
rtw_warn_on(1);
429
continue;
430
}
431
432
if (!CH_IS_NON_OCP(&ch_set[i]))
433
continue;
434
435
if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
436
&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
437
) {
438
ret = _TRUE;
439
break;
440
}
441
}
442
443
exit:
444
return ret;
445
}
446
447
bool rtw_chset_is_ch_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch)
448
{
449
return rtw_chset_is_chbw_non_ocp(ch_set, ch, CHANNEL_WIDTH_20, HAL_PRIME_CHNL_OFFSET_DONT_CARE);
450
}
451
452
u32 rtw_chset_get_ch_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
453
{
454
int ms = 0;
455
systime current_time;
456
u32 hi = 0, lo = 0;
457
int i;
458
459
if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
460
goto exit;
461
462
current_time = rtw_get_current_time();
463
464
for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
465
if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
466
rtw_warn_on(1);
467
continue;
468
}
469
470
if (!CH_IS_NON_OCP(&ch_set[i]))
471
continue;
472
473
if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
474
&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
475
) {
476
if (rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time) > ms)
477
ms = rtw_systime_to_ms(ch_set[i].non_ocp_end_time - current_time);
478
}
479
}
480
481
exit:
482
return ms;
483
}
484
485
/**
486
* rtw_chset_update_non_ocp - update non_ocp_end_time according to the given @ch, @bw, @offset into @ch_set
487
* @ch_set: the given channel set
488
* @ch: channel number on which radar is detected
489
* @bw: bandwidth on which radar is detected
490
* @offset: bandwidth offset on which radar is detected
491
* @ms: ms to add from now to update non_ocp_end_time, ms < 0 means use NON_OCP_TIME_MS
492
*/
493
static void _rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
494
{
495
u32 hi = 0, lo = 0;
496
int i;
497
498
if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE)
499
goto exit;
500
501
for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
502
if (!rtw_ch2freq(ch_set[i].ChannelNum)) {
503
rtw_warn_on(1);
504
continue;
505
}
506
507
if (lo <= rtw_ch2freq(ch_set[i].ChannelNum)
508
&& rtw_ch2freq(ch_set[i].ChannelNum) <= hi
509
) {
510
if (ms >= 0)
511
ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(ms);
512
else
513
ch_set[i].non_ocp_end_time = rtw_get_current_time() + rtw_ms_to_systime(NON_OCP_TIME_MS);
514
}
515
}
516
517
exit:
518
return;
519
}
520
521
inline void rtw_chset_update_non_ocp(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
522
{
523
_rtw_chset_update_non_ocp(ch_set, ch, bw, offset, -1);
524
}
525
526
inline void rtw_chset_update_non_ocp_ms(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset, int ms)
527
{
528
_rtw_chset_update_non_ocp(ch_set, ch, bw, offset, ms);
529
}
530
531
u32 rtw_get_ch_waiting_ms(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset, u32 *r_non_ocp_ms, u32 *r_cac_ms)
532
{
533
struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
534
u32 non_ocp_ms;
535
u32 cac_ms;
536
u8 in_rd_range = 0; /* if in current radar detection range*/
537
538
if (rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset))
539
non_ocp_ms = rtw_chset_get_ch_non_ocp_ms(rfctl->channel_set, ch, bw, offset);
540
else
541
non_ocp_ms = 0;
542
543
if (rfctl->radar_detect_enabled) {
544
u32 cur_hi, cur_lo, hi, lo;
545
546
if (rtw_chbw_to_freq_range(ch, bw, offset, &hi, &lo) == _FALSE) {
547
RTW_ERR("input range ch:%u, bw:%u, offset:%u\n", ch, bw, offset);
548
rtw_warn_on(1);
549
}
550
551
if (rtw_chbw_to_freq_range(rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset, &cur_hi, &cur_lo) == _FALSE) {
552
RTW_ERR("cur detection range ch:%u, bw:%u, offset:%u\n", rfctl->radar_detect_ch, rfctl->radar_detect_bw, rfctl->radar_detect_offset);
553
rtw_warn_on(1);
554
}
555
556
if (rtw_is_range_a_in_b(hi, lo, cur_hi, cur_lo))
557
in_rd_range = 1;
558
}
559
560
if (!rtw_is_dfs_chbw(ch, bw, offset))
561
cac_ms = 0;
562
else if (in_rd_range && !non_ocp_ms) {
563
if (IS_CH_WAITING(rfctl))
564
cac_ms = rtw_systime_to_ms(rfctl->cac_end_time - rtw_get_current_time());
565
else
566
cac_ms = 0;
567
} else if (rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(dvobj)))
568
cac_ms = CAC_TIME_CE_MS;
569
else
570
cac_ms = CAC_TIME_MS;
571
572
if (r_non_ocp_ms)
573
*r_non_ocp_ms = non_ocp_ms;
574
if (r_cac_ms)
575
*r_cac_ms = cac_ms;
576
577
return non_ocp_ms + cac_ms;
578
}
579
580
void rtw_reset_cac(struct rf_ctl_t *rfctl, u8 ch, u8 bw, u8 offset)
581
{
582
u32 non_ocp_ms;
583
u32 cac_ms;
584
585
rtw_get_ch_waiting_ms(rfctl
586
, ch
587
, bw
588
, offset
589
, &non_ocp_ms
590
, &cac_ms
591
);
592
593
rfctl->cac_start_time = rtw_get_current_time() + rtw_ms_to_systime(non_ocp_ms);
594
rfctl->cac_end_time = rfctl->cac_start_time + rtw_ms_to_systime(cac_ms);
595
596
/* skip special value */
597
if (rfctl->cac_start_time == RTW_CAC_STOPPED) {
598
rfctl->cac_start_time++;
599
rfctl->cac_end_time++;
600
}
601
if (rfctl->cac_end_time == RTW_CAC_STOPPED)
602
rfctl->cac_end_time++;
603
}
604
605
u32 rtw_force_stop_cac(struct rf_ctl_t *rfctl, u32 timeout_ms)
606
{
607
struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
608
systime start;
609
u32 pass_ms;
610
611
start = rtw_get_current_time();
612
613
rfctl->cac_force_stop = 1;
614
615
while (rtw_get_passing_time_ms(start) <= timeout_ms
616
&& IS_UNDER_CAC(rfctl)
617
) {
618
if (dev_is_surprise_removed(dvobj) || dev_is_drv_stopped(dvobj))
619
break;
620
rtw_msleep_os(20);
621
}
622
623
if (IS_UNDER_CAC(rfctl)) {
624
if (!dev_is_surprise_removed(dvobj) && !dev_is_drv_stopped(dvobj))
625
RTW_INFO("%s waiting for cac stop timeout!\n", __func__);
626
}
627
628
rfctl->cac_force_stop = 0;
629
630
pass_ms = rtw_get_passing_time_ms(start);
631
632
return pass_ms;
633
}
634
#endif /* CONFIG_DFS_MASTER */
635
636
/* choose channel with shortest waiting (non ocp + cac) time */
637
bool rtw_choose_shortest_waiting_ch(struct rf_ctl_t *rfctl, u8 sel_ch, u8 max_bw
638
, u8 *dec_ch, u8 *dec_bw, u8 *dec_offset
639
, u8 d_flags, u8 cur_ch, u8 same_band_prefer, u8 mesh_only)
640
{
641
#ifndef DBG_CHOOSE_SHORTEST_WAITING_CH
642
#define DBG_CHOOSE_SHORTEST_WAITING_CH 0
643
#endif
644
struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
645
struct registry_priv *regsty = dvobj_to_regsty(dvobj);
646
u8 ch, bw, offset;
647
u8 ch_c = 0, bw_c = 0, offset_c = 0;
648
int i;
649
u32 min_waiting_ms = 0;
650
651
if (!dec_ch || !dec_bw || !dec_offset) {
652
rtw_warn_on(1);
653
return _FALSE;
654
}
655
656
/* full search and narrow bw judegement first to avoid potetial judegement timing issue */
657
for (bw = CHANNEL_WIDTH_20; bw <= max_bw; bw++) {
658
if (!hal_is_bw_support(dvobj_get_primary_adapter(dvobj), bw))
659
continue;
660
661
for (i = 0; i < rfctl->max_chan_nums; i++) {
662
u32 non_ocp_ms = 0;
663
u32 cac_ms = 0;
664
u32 waiting_ms = 0;
665
666
ch = rfctl->channel_set[i].ChannelNum;
667
if (sel_ch > 0 && ch != sel_ch)
668
continue;
669
670
if ((d_flags & RTW_CHF_2G) && ch <= 14)
671
continue;
672
673
if ((d_flags & RTW_CHF_5G) && ch > 14)
674
continue;
675
676
if (ch > 14) {
677
if (bw > REGSTY_BW_5G(regsty))
678
continue;
679
} else {
680
if (bw > REGSTY_BW_2G(regsty))
681
continue;
682
}
683
684
if (mesh_only && ch >= 5 && ch <= 9 && bw > CHANNEL_WIDTH_20)
685
continue;
686
687
if (!rtw_get_offset_by_chbw(ch, bw, &offset))
688
continue;
689
690
if (!rtw_chset_is_chbw_valid(rfctl->channel_set, ch, bw, offset))
691
continue;
692
693
if ((d_flags & RTW_CHF_NON_OCP) && rtw_chset_is_chbw_non_ocp(rfctl->channel_set, ch, bw, offset))
694
continue;
695
696
if ((d_flags & RTW_CHF_DFS) && rtw_is_dfs_chbw(ch, bw, offset))
697
continue;
698
699
if ((d_flags & RTW_CHF_LONG_CAC) && rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(dvobj)))
700
continue;
701
702
if ((d_flags & RTW_CHF_NON_DFS) && !rtw_is_dfs_chbw(ch, bw, offset))
703
continue;
704
705
if ((d_flags & RTW_CHF_NON_LONG_CAC) && !rtw_is_long_cac_ch(ch, bw, offset, rtw_odm_get_dfs_domain(dvobj)))
706
continue;
707
708
#ifdef CONFIG_DFS_MASTER
709
waiting_ms = rtw_get_ch_waiting_ms(rfctl, ch, bw, offset, &non_ocp_ms, &cac_ms);
710
#endif
711
712
if (DBG_CHOOSE_SHORTEST_WAITING_CH)
713
RTW_INFO("%s:%u,%u,%u %u(non_ocp:%u, cac:%u)\n"
714
, __func__, ch, bw, offset, waiting_ms, non_ocp_ms, cac_ms);
715
716
if (ch_c == 0
717
/* first: smaller wating time */
718
|| min_waiting_ms > waiting_ms
719
/* then: wider bw */
720
|| (min_waiting_ms == waiting_ms && bw > bw_c)
721
/* then: same band if requested */
722
|| (same_band_prefer && min_waiting_ms == waiting_ms && bw == bw_c
723
&& !rtw_is_same_band(cur_ch, ch_c) && rtw_is_same_band(cur_ch, ch))
724
) {
725
ch_c = ch;
726
bw_c = bw;
727
offset_c = offset;
728
min_waiting_ms = waiting_ms;
729
}
730
}
731
}
732
733
if (ch_c != 0) {
734
RTW_INFO("%s: d_flags:0x%02x cur_ch:%u sb_prefer:%u%s %u,%u,%u waiting_ms:%u\n"
735
, __func__, d_flags, cur_ch, same_band_prefer
736
, mesh_only ? " mesh_only" : ""
737
, ch_c, bw_c, offset_c, min_waiting_ms);
738
739
*dec_ch = ch_c;
740
*dec_bw = bw_c;
741
*dec_offset = offset_c;
742
return _TRUE;
743
}
744
745
if (d_flags == 0) {
746
RTW_INFO("%s: sel_ch:%u max_bw:%u d_flags:0x%02x cur_ch:%u sb_prefer:%u%s\n"
747
, __func__, sel_ch, max_bw, d_flags, cur_ch, same_band_prefer
748
, mesh_only ? " mesh_only" : "");
749
rtw_warn_on(1);
750
}
751
752
return _FALSE;
753
}
754
755
void dump_chset(void *sel, RT_CHANNEL_INFO *ch_set)
756
{
757
u8 i;
758
759
for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
760
RTW_PRINT_SEL(sel, "ch:%3u, freq:%u, scan_type:%d"
761
, ch_set[i].ChannelNum, rtw_ch2freq(ch_set[i].ChannelNum), ch_set[i].ScanType);
762
763
#ifdef CONFIG_FIND_BEST_CHANNEL
764
_RTW_PRINT_SEL(sel, ", rx_count:%u", ch_set[i].rx_count);
765
#endif
766
767
#ifdef CONFIG_DFS_MASTER
768
if (rtw_is_dfs_ch(ch_set[i].ChannelNum)) {
769
if (CH_IS_NON_OCP(&ch_set[i]))
770
_RTW_PRINT_SEL(sel, ", non_ocp:%d"
771
, rtw_systime_to_ms(ch_set[i].non_ocp_end_time - rtw_get_current_time()));
772
else
773
_RTW_PRINT_SEL(sel, ", non_ocp:N/A");
774
}
775
#endif
776
777
_RTW_PRINT_SEL(sel, "\n");
778
}
779
780
RTW_PRINT_SEL(sel, "total ch number:%d\n", i);
781
}
782
783
void dump_cur_chset(void *sel, struct rf_ctl_t *rfctl)
784
{
785
struct dvobj_priv *dvobj = rfctl_to_dvobj(rfctl);
786
struct registry_priv *regsty = dvobj_to_regsty(dvobj);
787
int i;
788
789
if (rfctl->country_ent)
790
dump_country_chplan(sel, rfctl->country_ent);
791
else
792
RTW_PRINT_SEL(sel, "chplan:0x%02X\n", rfctl->ChannelPlan);
793
794
#if CONFIG_TXPWR_LIMIT
795
RTW_PRINT_SEL(sel, "PLS regd:%s\n", rfctl->regd_name);
796
#endif
797
798
#ifdef CONFIG_DFS_MASTER
799
RTW_PRINT_SEL(sel, "dfs_domain:%u\n", rtw_odm_get_dfs_domain(dvobj));
800
#endif
801
802
for (i = 0; i < MAX_CHANNEL_NUM; i++)
803
if (regsty->excl_chs[i] != 0)
804
break;
805
806
if (i < MAX_CHANNEL_NUM) {
807
RTW_PRINT_SEL(sel, "excl_chs:");
808
for (i = 0; i < MAX_CHANNEL_NUM; i++) {
809
if (regsty->excl_chs[i] == 0)
810
break;
811
_RTW_PRINT_SEL(sel, "%u ", regsty->excl_chs[i]);
812
}
813
_RTW_PRINT_SEL(sel, "\n");
814
}
815
816
dump_chset(sel, rfctl->channel_set);
817
}
818
819
/*
820
* Search the @param ch in given @param ch_set
821
* @ch_set: the given channel set
822
* @ch: the given channel number
823
*
824
* return the index of channel_num in channel_set, -1 if not found
825
*/
826
int rtw_chset_search_ch(RT_CHANNEL_INFO *ch_set, const u32 ch)
827
{
828
int i;
829
830
if (ch == 0)
831
return -1;
832
833
for (i = 0; i < MAX_CHANNEL_NUM && ch_set[i].ChannelNum != 0; i++) {
834
if (ch == ch_set[i].ChannelNum)
835
return i;
836
}
837
838
return -1;
839
}
840
841
/*
842
* Check if the @param ch, bw, offset is valid for the given @param ch_set
843
* @ch_set: the given channel set
844
* @ch: the given channel number
845
* @bw: the given bandwidth
846
* @offset: the given channel offset
847
*
848
* return valid (1) or not (0)
849
*/
850
u8 rtw_chset_is_chbw_valid(RT_CHANNEL_INFO *ch_set, u8 ch, u8 bw, u8 offset)
851
{
852
u8 cch;
853
u8 *op_chs;
854
u8 op_ch_num;
855
u8 valid = 0;
856
int i;
857
858
cch = rtw_get_center_ch(ch, bw, offset);
859
860
if (!rtw_get_op_chs_by_cch_bw(cch, bw, &op_chs, &op_ch_num))
861
goto exit;
862
863
for (i = 0; i < op_ch_num; i++) {
864
if (0)
865
RTW_INFO("%u,%u,%u - cch:%u, bw:%u, op_ch:%u\n", ch, bw, offset, cch, bw, *(op_chs + i));
866
if (rtw_chset_search_ch(ch_set, *(op_chs + i)) == -1)
867
break;
868
}
869
870
if (op_ch_num != 0 && i == op_ch_num)
871
valid = 1;
872
873
exit:
874
return valid;
875
}
876
877
/**
878
* rtw_chset_sync_chbw - obey g_ch, adjust g_bw, g_offset, bw, offset to fit in channel plan
879
* @ch_set: channel plan to check
880
* @req_ch: pointer of the request ch, may be modified further
881
* @req_bw: pointer of the request bw, may be modified further
882
* @req_offset: pointer of the request offset, may be modified further
883
* @g_ch: pointer of the ongoing group ch
884
* @g_bw: pointer of the ongoing group bw, may be modified further
885
* @g_offset: pointer of the ongoing group offset, may be modified further
886
*/
887
void rtw_chset_sync_chbw(RT_CHANNEL_INFO *ch_set, u8 *req_ch, u8 *req_bw, u8 *req_offset
888
, u8 *g_ch, u8 *g_bw, u8 *g_offset)
889
{
890
u8 r_ch, r_bw, r_offset;
891
u8 u_ch, u_bw, u_offset;
892
u8 cur_bw = *req_bw;
893
894
while (1) {
895
r_ch = *req_ch;
896
r_bw = cur_bw;
897
r_offset = *req_offset;
898
u_ch = *g_ch;
899
u_bw = *g_bw;
900
u_offset = *g_offset;
901
902
rtw_sync_chbw(&r_ch, &r_bw, &r_offset, &u_ch, &u_bw, &u_offset);
903
904
if (rtw_chset_is_chbw_valid(ch_set, r_ch, r_bw, r_offset))
905
break;
906
if (cur_bw == CHANNEL_WIDTH_20) {
907
rtw_warn_on(1);
908
break;
909
}
910
cur_bw--;
911
};
912
913
*req_ch = r_ch;
914
*req_bw = r_bw;
915
*req_offset = r_offset;
916
*g_ch = u_ch;
917
*g_bw = u_bw;
918
*g_offset = u_offset;
919
}
920
921
/*
922
* Check the @param ch is fit with setband setting of @param adapter
923
* @adapter: the given adapter
924
* @ch: the given channel number
925
*
926
* return _TRUE when check valid, _FALSE not valid
927
*/
928
bool rtw_mlme_band_check(_adapter *adapter, const u32 ch)
929
{
930
if (adapter->setband == WIFI_FREQUENCY_BAND_AUTO /* 2.4G and 5G */
931
|| (adapter->setband == WIFI_FREQUENCY_BAND_2GHZ && ch < 35) /* 2.4G only */
932
|| (adapter->setband == WIFI_FREQUENCY_BAND_5GHZ && ch > 35) /* 5G only */
933
)
934
return _TRUE;
935
return _FALSE;
936
}
937
inline void RTW_SET_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
938
{
939
int bs = ATOMIC_READ(&padapter->bandskip);
940
941
bs |= skip_band;
942
ATOMIC_SET(&padapter->bandskip, bs);
943
}
944
945
inline void RTW_CLR_SCAN_BAND_SKIP(_adapter *padapter, int skip_band)
946
{
947
int bs = ATOMIC_READ(&padapter->bandskip);
948
949
bs &= ~(skip_band);
950
ATOMIC_SET(&padapter->bandskip, bs);
951
}
952
inline int RTW_GET_SCAN_BAND_SKIP(_adapter *padapter)
953
{
954
return ATOMIC_READ(&padapter->bandskip);
955
}
956
957
#define RTW_IS_SCAN_BAND_SKIP(padapter, skip_band) (ATOMIC_READ(&padapter->bandskip) & (skip_band))
958
959
bool rtw_mlme_ignore_chan(_adapter *adapter, const u32 ch)
960
{
961
if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_24G) && ch < 35) /* SKIP 2.4G Band channel */
962
return _TRUE;
963
if (RTW_IS_SCAN_BAND_SKIP(adapter, BAND_5G) && ch > 35) /* SKIP 5G Band channel */
964
return _TRUE;
965
966
return _FALSE;
967
}
968
969
970
/****************************************************************************
971
972
Following are the initialization functions for WiFi MLME
973
974
*****************************************************************************/
975
976
int init_hw_mlme_ext(_adapter *padapter)
977
{
978
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
979
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
980
u8 rx_bar_enble = _TRUE;
981
982
/*
983
* Sync driver status and hardware setting
984
*/
985
986
/* Modify to make sure first time change channel(band) would be done properly */
987
pHalData->current_channel = 0;
988
pHalData->current_channel_bw = CHANNEL_WIDTH_MAX;
989
#ifdef CONFIG_IEEE80211_BAND_5GHZ
990
pHalData->current_band_type = BAND_MAX;
991
#else
992
pHalData->current_band_type = BAND_ON_2_4G;
993
#endif
994
995
/* set_opmode_cmd(padapter, infra_client_with_mlme); */ /* removed */
996
rtw_hal_set_hwreg(padapter, HW_VAR_ENABLE_RX_BAR, &rx_bar_enble);
997
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
998
999
return _SUCCESS;
1000
}
1001
1002
void init_mlme_default_rate_set(_adapter *padapter)
1003
{
1004
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1005
unsigned char end_set[1] = {0xff};
1006
u8 offset_datarate = 0;
1007
u8 offset_basicrate = 0;
1008
#ifdef CONFIG_80211N_HT
1009
unsigned char supported_mcs_set[16] = {0xff, 0xff, 0xff, 0xff, 0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
1010
#endif
1011
1012
if (IsSupportedTxCCK(padapter->registrypriv.wireless_mode)) {
1013
1014
unsigned char datarate_b[B_MODE_RATE_NUM] ={_1M_RATE_, _2M_RATE_, _5M_RATE_, _11M_RATE_};
1015
_rtw_memcpy(pmlmeext->datarate, datarate_b, B_MODE_RATE_NUM);
1016
_rtw_memcpy(pmlmeext->basicrate, datarate_b, B_MODE_RATE_NUM);
1017
offset_datarate += B_MODE_RATE_NUM;
1018
offset_basicrate += B_MODE_RATE_NUM;
1019
RTW_INFO("%s: support CCK\n", __func__);
1020
}
1021
if(IsSupportedTxOFDM(padapter->registrypriv.wireless_mode)) {
1022
unsigned char datarate_g[G_MODE_RATE_NUM] ={_6M_RATE_, _9M_RATE_, _12M_RATE_, _18M_RATE_,_24M_RATE_, _36M_RATE_, _48M_RATE_, _54M_RATE_};
1023
unsigned char basicrate_g[G_MODE_BASIC_RATE_NUM] = {_6M_RATE_, _12M_RATE_, _24M_RATE_};
1024
_rtw_memcpy(pmlmeext->datarate + offset_datarate, datarate_g, G_MODE_RATE_NUM);
1025
_rtw_memcpy(pmlmeext->basicrate + offset_basicrate,basicrate_g, G_MODE_BASIC_RATE_NUM);
1026
offset_datarate += G_MODE_RATE_NUM;
1027
offset_basicrate += G_MODE_BASIC_RATE_NUM;
1028
RTW_INFO("%s: support OFDM\n", __func__);
1029
1030
}
1031
_rtw_memcpy(pmlmeext->datarate + offset_datarate, end_set, 1);
1032
_rtw_memcpy(pmlmeext->basicrate + offset_basicrate, end_set, 1);
1033
1034
#ifdef CONFIG_80211N_HT
1035
if( padapter->registrypriv.ht_enable && is_supported_ht(padapter->registrypriv.wireless_mode))
1036
_rtw_memcpy(pmlmeext->default_supported_mcs_set, supported_mcs_set, sizeof(pmlmeext->default_supported_mcs_set));
1037
#endif
1038
}
1039
1040
static void init_mlme_ext_priv_value(_adapter *padapter)
1041
{
1042
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1043
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1044
1045
ATOMIC_SET(&pmlmeext->event_seq, 0);
1046
pmlmeext->mgnt_seq = 0;/* reset to zero when disconnect at client mode */
1047
#ifdef CONFIG_IEEE80211W
1048
pmlmeext->sa_query_seq = 0;
1049
#endif
1050
pmlmeext->cur_channel = padapter->registrypriv.channel;
1051
pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
1052
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1053
1054
pmlmeext->retry = 0;
1055
1056
pmlmeext->cur_wireless_mode = padapter->registrypriv.wireless_mode;
1057
init_mlme_default_rate_set(padapter);
1058
1059
if ((pmlmeext->cur_channel > 14) || ((padapter->registrypriv.wireless_mode & WIRELESS_11B) == 0))
1060
pmlmeext->tx_rate = IEEE80211_OFDM_RATE_6MB;
1061
else
1062
pmlmeext->tx_rate = IEEE80211_CCK_RATE_1MB;
1063
1064
mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
1065
pmlmeext->sitesurvey_res.channel_idx = 0;
1066
pmlmeext->sitesurvey_res.bss_cnt = 0;
1067
pmlmeext->sitesurvey_res.scan_ch_ms = SURVEY_TO;
1068
pmlmeext->sitesurvey_res.rx_ampdu_accept = RX_AMPDU_ACCEPT_INVALID;
1069
pmlmeext->sitesurvey_res.rx_ampdu_size = RX_AMPDU_SIZE_INVALID;
1070
#ifdef CONFIG_SCAN_BACKOP
1071
mlmeext_assign_scan_backop_flags_sta(pmlmeext, /*SS_BACKOP_EN|*/SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1072
#ifdef CONFIG_AP_MODE
1073
mlmeext_assign_scan_backop_flags_ap(pmlmeext, SS_BACKOP_EN | SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1074
#endif
1075
#ifdef CONFIG_RTW_MESH
1076
mlmeext_assign_scan_backop_flags_mesh(pmlmeext, /*SS_BACKOP_EN | */SS_BACKOP_PS_ANNC | SS_BACKOP_TX_RESUME);
1077
#endif
1078
pmlmeext->sitesurvey_res.scan_cnt = 0;
1079
pmlmeext->sitesurvey_res.scan_cnt_max = RTW_SCAN_NUM_OF_CH;
1080
pmlmeext->sitesurvey_res.backop_ms = RTW_BACK_OP_CH_MS;
1081
#endif
1082
#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
1083
pmlmeext->sitesurvey_res.is_sw_antdiv_bl_scan = 0;
1084
#endif
1085
pmlmeext->scan_abort = _FALSE;
1086
1087
pmlmeinfo->state = WIFI_FW_NULL_STATE;
1088
pmlmeinfo->reauth_count = 0;
1089
pmlmeinfo->reassoc_count = 0;
1090
pmlmeinfo->link_count = 0;
1091
pmlmeinfo->auth_seq = 0;
1092
pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
1093
pmlmeinfo->key_index = 0;
1094
pmlmeinfo->iv = 0;
1095
1096
pmlmeinfo->enc_algo = _NO_PRIVACY_;
1097
pmlmeinfo->authModeToggle = 0;
1098
1099
_rtw_memset(pmlmeinfo->chg_txt, 0, 128);
1100
1101
pmlmeinfo->slotTime = SHORT_SLOT_TIME;
1102
pmlmeinfo->preamble_mode = PREAMBLE_AUTO;
1103
1104
pmlmeinfo->dialogToken = 0;
1105
1106
pmlmeext->action_public_rxseq = 0xffff;
1107
pmlmeext->action_public_dialog_token = 0xff;
1108
#ifdef ROKU_PRIVATE
1109
/*infra mode, used to store AP's info*/
1110
_rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX);
1111
pmlmeinfo->ht_vht_received = 0;
1112
#endif /* ROKU_PRIVATE */
1113
}
1114
1115
void init_mlme_ext_timer(_adapter *padapter)
1116
{
1117
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1118
1119
rtw_init_timer(&pmlmeext->survey_timer, padapter, survey_timer_hdl, padapter);
1120
rtw_init_timer(&pmlmeext->link_timer, padapter, link_timer_hdl, padapter);
1121
#ifdef CONFIG_RTW_80211R
1122
rtw_init_timer(&pmlmeext->ft_link_timer, padapter, rtw_ft_link_timer_hdl, padapter);
1123
rtw_init_timer(&pmlmeext->ft_roam_timer, padapter, rtw_ft_roam_timer_hdl, padapter);
1124
#endif
1125
1126
#ifdef CONFIG_RTW_REPEATER_SON
1127
rtw_init_timer(&pmlmeext->rson_scan_timer, padapter, rson_timer_hdl, padapter);
1128
#endif
1129
}
1130
1131
int init_mlme_ext_priv(_adapter *padapter)
1132
{
1133
int res = _SUCCESS;
1134
struct registry_priv *pregistrypriv = &padapter->registrypriv;
1135
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1136
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1137
1138
/* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
1139
/* _rtw_memset((u8 *)pmlmeext, 0, sizeof(struct mlme_ext_priv)); */
1140
1141
pmlmeext->padapter = padapter;
1142
1143
/* fill_fwpriv(padapter, &(pmlmeext->fwpriv)); */
1144
1145
init_mlme_ext_priv_value(padapter);
1146
pmlmeinfo->bAcceptAddbaReq = pregistrypriv->bAcceptAddbaReq;
1147
1148
init_mlme_ext_timer(padapter);
1149
1150
#ifdef CONFIG_AP_MODE
1151
init_mlme_ap_info(padapter);
1152
#endif
1153
1154
pmlmeext->last_scan_time = 0;
1155
pmlmeext->mlmeext_init = _TRUE;
1156
1157
1158
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
1159
pmlmeext->active_keep_alive_check = _TRUE;
1160
#else
1161
pmlmeext->active_keep_alive_check = _FALSE;
1162
#endif
1163
1164
#ifdef DBG_FIXED_CHAN
1165
pmlmeext->fixed_chan = 0xFF;
1166
#endif
1167
1168
pmlmeext->tsf_update_pause_factor = pregistrypriv->tsf_update_pause_factor;
1169
pmlmeext->tsf_update_restore_factor = pregistrypriv->tsf_update_restore_factor;
1170
1171
#ifdef CONFIG_SUPPORT_STATIC_SMPS
1172
pmlmeext->ssmps_en = _FALSE;
1173
pmlmeext->ssmps_tx_tp_th = SSMPS_TX_TP_TH;/*Mbps*/
1174
pmlmeext->ssmps_rx_tp_th = SSMPS_RX_TP_TH;/*Mbps*/
1175
#ifdef DBG_STATIC_SMPS
1176
pmlmeext->ssmps_test = _FALSE;
1177
#endif
1178
#endif
1179
1180
#ifdef CONFIG_CTRL_TXSS_BY_TP
1181
pmlmeext->txss_ctrl_en = _TRUE;
1182
pmlmeext->txss_tp_th = TXSS_TP_TH;
1183
pmlmeext->txss_tp_chk_cnt = TXSS_TP_CHK_CNT;
1184
#endif
1185
1186
return res;
1187
1188
}
1189
1190
void free_mlme_ext_priv(struct mlme_ext_priv *pmlmeext)
1191
{
1192
_adapter *padapter = pmlmeext->padapter;
1193
1194
if (!padapter)
1195
return;
1196
1197
if (rtw_is_drv_stopped(padapter)) {
1198
_cancel_timer_ex(&pmlmeext->survey_timer);
1199
_cancel_timer_ex(&pmlmeext->link_timer);
1200
}
1201
}
1202
1203
#ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1204
static u8 cmp_pkt_chnl_diff(_adapter *padapter, u8 *pframe, uint packet_len)
1205
{
1206
/* if the channel is same, return 0. else return channel differential */
1207
uint len;
1208
u8 channel;
1209
u8 *p;
1210
1211
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, _DSSET_IE_, &len, packet_len - _BEACON_IE_OFFSET_);
1212
if (p) {
1213
channel = *(p + 2);
1214
if (padapter->mlmeextpriv.cur_channel >= channel)
1215
return padapter->mlmeextpriv.cur_channel - channel;
1216
else
1217
return channel - padapter->mlmeextpriv.cur_channel;
1218
} else
1219
return 0;
1220
}
1221
#endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
1222
1223
static void _mgt_dispatcher(_adapter *padapter, struct mlme_handler *ptable, union recv_frame *precv_frame)
1224
{
1225
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1226
u8 *pframe = precv_frame->u.hdr.rx_data;
1227
1228
if (ptable->func) {
1229
/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1230
if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1231
!_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1232
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
1233
{
1234
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1235
1236
if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE)
1237
return;
1238
1239
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE)
1240
return;
1241
1242
if ( pwdev_priv->pno_mac_addr[0] == 0xFF)
1243
return;
1244
1245
if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_pno_mac_addr(padapter), ETH_ALEN))
1246
return;
1247
}
1248
#else
1249
return;
1250
#endif
1251
1252
ptable->func(padapter, precv_frame);
1253
}
1254
1255
}
1256
1257
void mgt_dispatcher(_adapter *padapter, union recv_frame *precv_frame)
1258
{
1259
int index;
1260
struct mlme_handler *ptable;
1261
u8 bc_addr[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1262
u8 *pframe = precv_frame->u.hdr.rx_data;
1263
struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, get_addr2_ptr(pframe));
1264
struct recv_priv *precvpriv = &padapter->recvpriv;
1265
1266
1267
#if 0
1268
{
1269
u8 *pbuf;
1270
pbuf = GetAddr1Ptr(pframe);
1271
RTW_INFO("A1-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1272
pbuf = get_addr2_ptr(pframe);
1273
RTW_INFO("A2-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1274
pbuf = GetAddr3Ptr(pframe);
1275
RTW_INFO("A3-%x:%x:%x:%x:%x:%x\n", *pbuf, *(pbuf + 1), *(pbuf + 2), *(pbuf + 3), *(pbuf + 4), *(pbuf + 5));
1276
}
1277
#endif
1278
1279
if (GetFrameType(pframe) != WIFI_MGT_TYPE) {
1280
return;
1281
}
1282
1283
/* receive the frames that ra(a1) is my address or ra(a1) is bc address. */
1284
if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN) &&
1285
!_rtw_memcmp(GetAddr1Ptr(pframe), bc_addr, ETH_ALEN))
1286
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
1287
{
1288
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
1289
1290
if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) != _TRUE)
1291
return;
1292
1293
if (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _TRUE)
1294
return;
1295
1296
if ( pwdev_priv->pno_mac_addr[0] == 0xFF)
1297
return;
1298
1299
if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_pno_mac_addr(padapter), ETH_ALEN))
1300
return;
1301
}
1302
#else
1303
return;
1304
#endif
1305
1306
ptable = mlme_sta_tbl;
1307
1308
index = get_frame_sub_type(pframe) >> 4;
1309
1310
#ifdef CONFIG_TDLS
1311
if ((index << 4) == WIFI_ACTION) {
1312
/* category==public (4), action==TDLS_DISCOVERY_RESPONSE */
1313
if (*(pframe + 24) == RTW_WLAN_CATEGORY_PUBLIC && *(pframe + 25) == TDLS_DISCOVERY_RESPONSE) {
1314
RTW_INFO("[TDLS] Recv %s from "MAC_FMT"\n", rtw_tdls_action_txt(TDLS_DISCOVERY_RESPONSE), MAC_ARG(get_addr2_ptr(pframe)));
1315
On_TDLS_Dis_Rsp(padapter, precv_frame);
1316
}
1317
}
1318
#endif /* CONFIG_TDLS */
1319
1320
if (index >= (sizeof(mlme_sta_tbl) / sizeof(struct mlme_handler))) {
1321
return;
1322
}
1323
ptable += index;
1324
1325
#if 1
1326
if (psta != NULL) {
1327
if (GetRetry(pframe)) {
1328
if (precv_frame->u.hdr.attrib.seq_num == psta->RxMgmtFrameSeqNum) {
1329
/* drop the duplicate management frame */
1330
precvpriv->dbg_rx_dup_mgt_frame_drop_count++;
1331
RTW_INFO("Drop duplicate management frame with seq_num = %d.\n", precv_frame->u.hdr.attrib.seq_num);
1332
return;
1333
}
1334
}
1335
psta->RxMgmtFrameSeqNum = precv_frame->u.hdr.attrib.seq_num;
1336
}
1337
#else
1338
1339
if (GetRetry(pframe)) {
1340
/* return; */
1341
}
1342
#endif
1343
1344
#ifdef CONFIG_AP_MODE
1345
switch (get_frame_sub_type(pframe)) {
1346
case WIFI_AUTH:
1347
if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter))
1348
ptable->func = &OnAuth;
1349
else
1350
ptable->func = &OnAuthClient;
1351
/* fall through */
1352
case WIFI_ASSOCREQ:
1353
case WIFI_REASSOCREQ:
1354
_mgt_dispatcher(padapter, ptable, precv_frame);
1355
#ifdef CONFIG_HOSTAPD_MLME
1356
if (MLME_IS_AP(padapter))
1357
rtw_hostapd_mlme_rx(padapter, precv_frame);
1358
#endif
1359
break;
1360
case WIFI_PROBEREQ:
1361
_mgt_dispatcher(padapter, ptable, precv_frame);
1362
#ifdef CONFIG_HOSTAPD_MLME
1363
if (MLME_IS_AP(padapter))
1364
rtw_hostapd_mlme_rx(padapter, precv_frame);
1365
#endif
1366
break;
1367
case WIFI_BEACON:
1368
_mgt_dispatcher(padapter, ptable, precv_frame);
1369
break;
1370
case WIFI_ACTION:
1371
_mgt_dispatcher(padapter, ptable, precv_frame);
1372
break;
1373
default:
1374
_mgt_dispatcher(padapter, ptable, precv_frame);
1375
#ifdef CONFIG_HOSTAPD_MLME
1376
if (MLME_IS_AP(padapter))
1377
rtw_hostapd_mlme_rx(padapter, precv_frame);
1378
#endif
1379
break;
1380
}
1381
#else
1382
1383
_mgt_dispatcher(padapter, ptable, precv_frame);
1384
1385
#endif
1386
1387
}
1388
1389
#ifdef CONFIG_P2P
1390
u32 p2p_listen_state_process(_adapter *padapter, unsigned char *da)
1391
{
1392
bool response = _TRUE;
1393
1394
#ifdef CONFIG_IOCTL_CFG80211
1395
if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
1396
if (rtw_cfg80211_get_is_roch(padapter) == _FALSE
1397
|| rtw_get_oper_ch(padapter) != padapter->wdinfo.listen_channel
1398
|| adapter_wdev_data(padapter)->p2p_enabled == _FALSE
1399
|| padapter->mlmepriv.wps_probe_resp_ie == NULL
1400
|| padapter->mlmepriv.p2p_probe_resp_ie == NULL
1401
) {
1402
#ifdef CONFIG_DEBUG_CFG80211
1403
RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: p2p_enabled:%d, wps_probe_resp_ie:%p, p2p_probe_resp_ie:%p\n"
1404
, ADPT_ARG(padapter)
1405
, adapter_wdev_data(padapter)->p2p_enabled
1406
, padapter->mlmepriv.wps_probe_resp_ie
1407
, padapter->mlmepriv.p2p_probe_resp_ie);
1408
RTW_INFO(ADPT_FMT" DON'T issue_probersp_p2p: is_ro_ch:%d, op_ch:%d, p2p_listen_channel:%d\n"
1409
, ADPT_ARG(padapter)
1410
, rtw_cfg80211_get_is_roch(padapter)
1411
, rtw_get_oper_ch(padapter)
1412
, padapter->wdinfo.listen_channel);
1413
#endif
1414
response = _FALSE;
1415
}
1416
} else
1417
#endif /* CONFIG_IOCTL_CFG80211 */
1418
if (padapter->wdinfo.driver_interface == DRIVER_WEXT) {
1419
/* do nothing if the device name is empty */
1420
if (!padapter->wdinfo.device_name_len)
1421
response = _FALSE;
1422
}
1423
1424
if (response == _TRUE)
1425
issue_probersp_p2p(padapter, da);
1426
1427
return _SUCCESS;
1428
}
1429
#endif /* CONFIG_P2P */
1430
1431
1432
/****************************************************************************
1433
1434
Following are the callback functions for each subtype of the management frames
1435
1436
*****************************************************************************/
1437
1438
unsigned int OnProbeReq(_adapter *padapter, union recv_frame *precv_frame)
1439
{
1440
unsigned int ielen;
1441
unsigned char *p;
1442
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1443
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1444
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1445
WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
1446
u8 *pframe = precv_frame->u.hdr.rx_data;
1447
uint len = precv_frame->u.hdr.len;
1448
u8 is_valid_p2p_probereq = _FALSE;
1449
1450
#ifdef CONFIG_ATMEL_RC_PATCH
1451
u8 *target_ie = NULL, *wps_ie = NULL;
1452
u8 *start;
1453
uint search_len = 0, wps_ielen = 0, target_ielen = 0;
1454
struct sta_info *psta;
1455
struct sta_priv *pstapriv = &padapter->stapriv;
1456
#endif
1457
1458
1459
#ifdef CONFIG_P2P
1460
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
1461
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1462
u8 wifi_test_chk_rate = 1;
1463
1464
#ifdef CONFIG_IOCTL_CFG80211
1465
if ((pwdinfo->driver_interface == DRIVER_CFG80211)
1466
&& !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)
1467
&& (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_PROBE_REQ) == _TRUE)
1468
) {
1469
rtw_cfg80211_rx_probe_request(padapter, precv_frame);
1470
return _SUCCESS;
1471
}
1472
#endif /* CONFIG_IOCTL_CFG80211 */
1473
1474
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) &&
1475
!rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE) &&
1476
!rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT) &&
1477
!rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH) &&
1478
!rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
1479
) {
1480
/* Commented by Albert 2011/03/17 */
1481
/* mcs_rate = 0->CCK 1M rate */
1482
/* mcs_rate = 1->CCK 2M rate */
1483
/* mcs_rate = 2->CCK 5.5M rate */
1484
/* mcs_rate = 3->CCK 11M rate */
1485
/* In the P2P mode, the driver should not support the CCK rate */
1486
1487
/* Commented by Kurt 2012/10/16 */
1488
/* IOT issue: Google Nexus7 use 1M rate to send p2p_probe_req after GO nego completed and Nexus7 is client */
1489
if (padapter->registrypriv.wifi_spec == 1) {
1490
if (pattrib->data_rate <= DESC_RATE11M)
1491
wifi_test_chk_rate = 0;
1492
}
1493
1494
if (wifi_test_chk_rate == 1) {
1495
is_valid_p2p_probereq = process_probe_req_p2p_ie(pwdinfo, pframe, len);
1496
if (is_valid_p2p_probereq == _TRUE) {
1497
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE)) {
1498
/* FIXME */
1499
if (padapter->wdinfo.driver_interface == DRIVER_WEXT)
1500
report_survey_event(padapter, precv_frame);
1501
1502
p2p_listen_state_process(padapter, get_sa(pframe));
1503
1504
return _SUCCESS;
1505
}
1506
1507
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO))
1508
goto _continue;
1509
}
1510
}
1511
}
1512
1513
_continue:
1514
#endif /* CONFIG_P2P */
1515
1516
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
1517
return _SUCCESS;
1518
1519
if (check_fwstate(pmlmepriv, _FW_LINKED) == _FALSE &&
1520
check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE | WIFI_MESH_STATE) == _FALSE)
1521
return _SUCCESS;
1522
1523
1524
/* RTW_INFO("+OnProbeReq\n"); */
1525
1526
1527
#ifdef CONFIG_ATMEL_RC_PATCH
1528
wps_ie = rtw_get_wps_ie(
1529
pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_,
1530
len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_,
1531
NULL, &wps_ielen);
1532
if (wps_ie)
1533
target_ie = rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_MANUFACTURER, NULL, &target_ielen);
1534
if ((target_ie && (target_ielen == 4)) && (_TRUE == _rtw_memcmp((void *)target_ie, "Ozmo", 4))) {
1535
/* psta->flag_atmel_rc = 1; */
1536
unsigned char *sa_addr = get_sa(pframe);
1537
printk("%s: Find Ozmo RC -- %02x:%02x:%02x:%02x:%02x:%02x \n\n",
1538
__func__, *sa_addr, *(sa_addr + 1), *(sa_addr + 2), *(sa_addr + 3), *(sa_addr + 4), *(sa_addr + 5));
1539
_rtw_memcpy(pstapriv->atmel_rc_pattern, get_sa(pframe), ETH_ALEN);
1540
}
1541
#endif
1542
1543
1544
#ifdef CONFIG_AUTO_AP_MODE
1545
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1546
pmlmepriv->cur_network.join_res == _TRUE) {
1547
_irqL irqL;
1548
struct sta_info *psta;
1549
u8 *mac_addr, *peer_addr;
1550
struct sta_priv *pstapriv = &padapter->stapriv;
1551
u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
1552
/* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
1553
1554
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _VENDOR_SPECIFIC_IE_, (int *)&ielen,
1555
len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1556
1557
if (!p || ielen != 14)
1558
goto _non_rc_device;
1559
1560
if (!_rtw_memcmp(p + 2, RC_OUI, sizeof(RC_OUI)))
1561
goto _non_rc_device;
1562
1563
if (!_rtw_memcmp(p + 6, get_sa(pframe), ETH_ALEN)) {
1564
RTW_INFO("%s, do rc pairing ("MAC_FMT"), but mac addr mismatch!("MAC_FMT")\n", __FUNCTION__,
1565
MAC_ARG(get_sa(pframe)), MAC_ARG(p + 6));
1566
1567
goto _non_rc_device;
1568
}
1569
1570
RTW_INFO("%s, got the pairing device("MAC_FMT")\n", __FUNCTION__, MAC_ARG(get_sa(pframe)));
1571
1572
/* new a station */
1573
psta = rtw_get_stainfo(pstapriv, get_sa(pframe));
1574
if (psta == NULL) {
1575
/* allocate a new one */
1576
RTW_INFO("going to alloc stainfo for rc="MAC_FMT"\n", MAC_ARG(get_sa(pframe)));
1577
psta = rtw_alloc_stainfo(pstapriv, get_sa(pframe));
1578
if (psta == NULL) {
1579
/* TODO: */
1580
RTW_INFO(" Exceed the upper limit of supported clients...\n");
1581
return _SUCCESS;
1582
}
1583
1584
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1585
if (rtw_is_list_empty(&psta->asoc_list)) {
1586
psta->expire_to = pstapriv->expire_to;
1587
rtw_list_insert_tail(&psta->asoc_list, &pstapriv->asoc_list);
1588
pstapriv->asoc_list_cnt++;
1589
}
1590
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
1591
1592
/* generate pairing ID */
1593
mac_addr = adapter_mac_addr(padapter);
1594
peer_addr = psta->cmn.mac_addr;
1595
psta->pid = (u16)(((mac_addr[4] << 8) + mac_addr[5]) + ((peer_addr[4] << 8) + peer_addr[5]));
1596
1597
/* update peer stainfo */
1598
psta->isrc = _TRUE;
1599
1600
/* AID assignment */
1601
if (psta->cmn.aid > 0)
1602
RTW_INFO(FUNC_ADPT_FMT" old AID=%d\n", FUNC_ADPT_ARG(padapter), psta->cmn.aid);
1603
else {
1604
if (!rtw_aid_alloc(padapter, psta)) {
1605
RTW_INFO(FUNC_ADPT_FMT" no room for more AIDs\n", FUNC_ADPT_ARG(padapter));
1606
return _SUCCESS;
1607
}
1608
RTW_INFO(FUNC_ADPT_FMT" allocate new AID=%d\n", FUNC_ADPT_ARG(padapter), psta->cmn.aid);
1609
}
1610
1611
psta->qos_option = 1;
1612
psta->cmn.bw_mode = CHANNEL_WIDTH_20;
1613
psta->ieee8021x_blocked = _FALSE;
1614
#ifdef CONFIG_80211N_HT
1615
if(padapter->registrypriv.ht_enable &&
1616
is_supported_ht(padapter->registrypriv.wireless_mode)) {
1617
psta->htpriv.ht_option = _TRUE;
1618
psta->htpriv.ampdu_enable = _FALSE;
1619
psta->htpriv.sgi_20m = _FALSE;
1620
psta->htpriv.sgi_40m = _FALSE;
1621
psta->htpriv.ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1622
psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
1623
psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
1624
}
1625
#endif
1626
1627
rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
1628
1629
_rtw_memset((void *)&psta->sta_stats, 0, sizeof(struct stainfo_stats));
1630
1631
_enter_critical_bh(&psta->lock, &irqL);
1632
psta->state |= _FW_LINKED;
1633
_exit_critical_bh(&psta->lock, &irqL);
1634
1635
report_add_sta_event(padapter, psta->cmn.mac_addr);
1636
1637
}
1638
1639
issue_probersp(padapter, get_sa(pframe), _FALSE);
1640
1641
return _SUCCESS;
1642
1643
}
1644
1645
_non_rc_device:
1646
1647
return _SUCCESS;
1648
1649
#endif /* CONFIG_AUTO_AP_MODE */
1650
1651
1652
#ifdef CONFIG_CONCURRENT_MODE
1653
if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
1654
rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) {
1655
/* don't process probe req */
1656
return _SUCCESS;
1657
}
1658
#endif
1659
1660
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, _SSID_IE_, (int *)&ielen,
1661
len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1662
1663
1664
/* check (wildcard) SSID */
1665
if (p != NULL) {
1666
if (is_valid_p2p_probereq == _TRUE)
1667
goto _issue_probersp;
1668
1669
if ((ielen != 0 && _FALSE == _rtw_memcmp((void *)(p + 2), (void *)cur->Ssid.Ssid, cur->Ssid.SsidLength))
1670
|| (ielen == 0 && pmlmeinfo->hidden_ssid_mode))
1671
goto exit;
1672
1673
#ifdef CONFIG_RTW_MESH
1674
if (MLME_IS_MESH(padapter)) {
1675
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _PROBEREQ_IE_OFFSET_, WLAN_EID_MESH_ID, (int *)&ielen,
1676
len - WLAN_HDR_A3_LEN - _PROBEREQ_IE_OFFSET_);
1677
1678
if (!p)
1679
goto exit;
1680
if (ielen != 0 && _rtw_memcmp((void *)(p + 2), (void *)cur->mesh_id.Ssid, cur->mesh_id.SsidLength) == _FALSE)
1681
goto exit;
1682
}
1683
#endif
1684
1685
_issue_probersp:
1686
if (((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE &&
1687
pmlmepriv->cur_network.join_res == _TRUE)) || check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
1688
/* RTW_INFO("+issue_probersp during ap mode\n"); */
1689
issue_probersp(padapter, get_sa(pframe), is_valid_p2p_probereq);
1690
}
1691
1692
}
1693
1694
exit:
1695
return _SUCCESS;
1696
1697
}
1698
1699
unsigned int OnProbeRsp(_adapter *padapter, union recv_frame *precv_frame)
1700
{
1701
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1702
u8 *pframe = precv_frame->u.hdr.rx_data;
1703
#ifdef CONFIG_P2P
1704
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
1705
#endif
1706
1707
1708
#ifdef CONFIG_P2P
1709
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ)) {
1710
if (_TRUE == pwdinfo->tx_prov_disc_info.benable) {
1711
if (_rtw_memcmp(pwdinfo->tx_prov_disc_info.peerIFAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
1712
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
1713
pwdinfo->tx_prov_disc_info.benable = _FALSE;
1714
issue_p2p_provision_request(padapter,
1715
pwdinfo->tx_prov_disc_info.ssid.Ssid,
1716
pwdinfo->tx_prov_disc_info.ssid.SsidLength,
1717
pwdinfo->tx_prov_disc_info.peerDevAddr);
1718
} else if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_DEVICE) || rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
1719
pwdinfo->tx_prov_disc_info.benable = _FALSE;
1720
issue_p2p_provision_request(padapter,
1721
NULL,
1722
0,
1723
pwdinfo->tx_prov_disc_info.peerDevAddr);
1724
}
1725
}
1726
}
1727
return _SUCCESS;
1728
} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
1729
if (_TRUE == pwdinfo->nego_req_info.benable) {
1730
RTW_INFO("[%s] P2P State is GONEGO ING!\n", __FUNCTION__);
1731
if (_rtw_memcmp(pwdinfo->nego_req_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN)) {
1732
pwdinfo->nego_req_info.benable = _FALSE;
1733
issue_p2p_GO_request(padapter, pwdinfo->nego_req_info.peerDevAddr);
1734
}
1735
}
1736
} else if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_INVITE_REQ)) {
1737
if (_TRUE == pwdinfo->invitereq_info.benable) {
1738
RTW_INFO("[%s] P2P_STATE_TX_INVITE_REQ!\n", __FUNCTION__);
1739
if (_rtw_memcmp(pwdinfo->invitereq_info.peer_macaddr, get_addr2_ptr(pframe), ETH_ALEN)) {
1740
pwdinfo->invitereq_info.benable = _FALSE;
1741
issue_p2p_invitation_request(padapter, pwdinfo->invitereq_info.peer_macaddr);
1742
}
1743
}
1744
}
1745
#endif
1746
1747
1748
if ((mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
1749
|| (MLME_IS_MESH(padapter) && check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE))
1750
#ifdef CONFIG_RTW_REPEATER_SON
1751
|| (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS)
1752
#endif
1753
) {
1754
rtw_mi_report_survey_event(padapter, precv_frame);
1755
return _SUCCESS;
1756
}
1757
1758
#if 0 /* move to validate_recv_mgnt_frame */
1759
if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
1760
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
1761
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
1762
if (psta != NULL)
1763
psta->sta_stats.rx_mgnt_pkts++;
1764
}
1765
}
1766
#endif
1767
1768
return _SUCCESS;
1769
1770
}
1771
1772
/* for 11n Logo 4.2.31/4.2.32 */
1773
static void rtw_check_legacy_ap(_adapter *padapter, u8 *pframe, u32 len)
1774
{
1775
1776
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1777
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1778
1779
if (!padapter->registrypriv.wifi_spec)
1780
return;
1781
1782
if(!MLME_IS_AP(padapter))
1783
return;
1784
1785
1786
if (pmlmeext->bstart_bss == _TRUE) {
1787
int left;
1788
unsigned char *pos;
1789
struct rtw_ieee802_11_elems elems;
1790
#ifdef CONFIG_80211N_HT
1791
u16 cur_op_mode;
1792
#endif
1793
/* checking IEs */
1794
left = len - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_;
1795
pos = pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_;
1796
if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
1797
RTW_INFO("%s: parse fail for "MAC_FMT"\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
1798
return;
1799
}
1800
#ifdef CONFIG_80211N_HT
1801
cur_op_mode = pmlmepriv->ht_op_mode & HT_INFO_OPERATION_MODE_OP_MODE_MASK;
1802
#endif
1803
/* for legacy ap */
1804
if (elems.ht_capabilities == NULL && elems.ht_capabilities_len == 0) {
1805
1806
if (0)
1807
RTW_INFO("%s: "MAC_FMT" is legacy ap\n", __func__, MAC_ARG(GetAddr3Ptr(pframe)));
1808
1809
ATOMIC_SET(&pmlmepriv->olbc, _TRUE);
1810
ATOMIC_SET(&pmlmepriv->olbc_ht, _TRUE);
1811
}
1812
1813
}
1814
}
1815
1816
unsigned int OnBeacon(_adapter *padapter, union recv_frame *precv_frame)
1817
{
1818
struct sta_info *psta;
1819
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1820
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
1821
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1822
struct sta_priv *pstapriv = &padapter->stapriv;
1823
u8 *pframe = precv_frame->u.hdr.rx_data;
1824
uint len = precv_frame->u.hdr.len;
1825
WLAN_BSSID_EX *pbss;
1826
int ret = _SUCCESS;
1827
#ifdef CONFIG_TDLS
1828
struct sta_info *ptdls_sta;
1829
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
1830
#ifdef CONFIG_TDLS_CH_SW
1831
struct tdls_ch_switch *pchsw_info = &padapter->tdlsinfo.chsw_info;
1832
#endif
1833
#endif /* CONFIG_TDLS */
1834
1835
if (validate_beacon_len(pframe, len) == _FALSE)
1836
return _SUCCESS;
1837
1838
if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS)
1839
|| (MLME_IS_MESH(padapter) && check_fwstate(pmlmepriv, WIFI_ASOC_STATE))
1840
) {
1841
rtw_mi_report_survey_event(padapter, precv_frame);
1842
return _SUCCESS;
1843
}
1844
#ifdef CONFIG_RTW_REPEATER_SON
1845
if (padapter->rtw_rson_scanstage == RSON_SCAN_PROCESS)
1846
rtw_mi_report_survey_event(padapter, precv_frame);
1847
#endif
1848
1849
rtw_check_legacy_ap(padapter, pframe, len);
1850
1851
if (_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)) {
1852
if ((pmlmeinfo->state & WIFI_FW_AUTH_NULL)
1853
&& (rtw_sta_linking_test_wait_done() || pmlmeext->join_abort)
1854
) {
1855
if (rtw_sta_linking_test_force_fail() || pmlmeext->join_abort) {
1856
set_link_timer(pmlmeext, 1);
1857
return _SUCCESS;
1858
}
1859
1860
/* we should update current network before auth, or some IE is wrong */
1861
pbss = (WLAN_BSSID_EX *)rtw_malloc(sizeof(WLAN_BSSID_EX));
1862
if (pbss) {
1863
if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
1864
struct beacon_keys recv_beacon;
1865
1866
update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
1867
1868
/* update bcn keys */
1869
if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
1870
RTW_INFO("%s: beacon keys ready\n", __func__);
1871
_rtw_memcpy(&pmlmepriv->cur_beacon_keys,
1872
&recv_beacon, sizeof(recv_beacon));
1873
} else {
1874
RTW_ERR("%s: get beacon keys failed\n", __func__);
1875
_rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
1876
}
1877
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
1878
pmlmepriv->new_beacon_cnts = 0;
1879
#endif
1880
}
1881
rtw_mfree((u8 *)pbss, sizeof(WLAN_BSSID_EX));
1882
}
1883
1884
/* check the vendor of the assoc AP */
1885
pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pframe + sizeof(struct rtw_ieee80211_hdr_3addr), len - sizeof(struct rtw_ieee80211_hdr_3addr));
1886
1887
/* update TSF Value */
1888
update_TSF(pmlmeext, pframe, len);
1889
pmlmeext->bcn_cnt = 0;
1890
pmlmeext->last_bcn_cnt = 0;
1891
1892
#ifdef CONFIG_P2P_PS
1893
/* Comment by YiWei , in wifi p2p spec the "3.3 P2P Power Management" , "These mechanisms are available in a P2P Group in which only P2P Devices are associated." */
1894
/* process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)); */
1895
#endif /* CONFIG_P2P_PS */
1896
1897
#if defined(CONFIG_P2P) && defined(CONFIG_CONCURRENT_MODE)
1898
if (padapter->registrypriv.wifi_spec) {
1899
if (process_p2p_cross_connect_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN)) == _FALSE) {
1900
if (rtw_mi_buddy_check_mlmeinfo_state(padapter, WIFI_FW_AP_STATE)) {
1901
RTW_PRINT("no issue auth, P2P cross-connect does not permit\n ");
1902
return _SUCCESS;
1903
}
1904
}
1905
}
1906
#endif /* CONFIG_P2P CONFIG_P2P and CONFIG_CONCURRENT_MODE */
1907
1908
/* start auth */
1909
start_clnt_auth(padapter);
1910
1911
return _SUCCESS;
1912
}
1913
1914
if (((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) && (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
1915
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
1916
if (psta != NULL) {
1917
#ifdef CONFIG_PATCH_JOIN_WRONG_CHANNEL
1918
/* Merge from 8712 FW code */
1919
if (cmp_pkt_chnl_diff(padapter, pframe, len) != 0) {
1920
/* join wrong channel, deauth and reconnect */
1921
issue_deauth(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_DEAUTH_LEAVING);
1922
1923
report_del_sta_event(padapter, (&(pmlmeinfo->network))->MacAddress, WLAN_REASON_JOIN_WRONG_CHANNEL, _TRUE, _FALSE);
1924
pmlmeinfo->state &= (~WIFI_FW_ASSOC_SUCCESS);
1925
return _SUCCESS;
1926
}
1927
#endif /* CONFIG_PATCH_JOIN_WRONG_CHANNEL */
1928
#ifdef CONFIG_RTW_80211R
1929
rtw_ft_update_bcn(padapter, precv_frame);
1930
#endif
1931
ret = rtw_check_bcn_info(padapter, pframe, len);
1932
if (!ret) {
1933
RTW_PRINT("ap has changed, disconnect now\n ");
1934
receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 0, _FALSE);
1935
return _SUCCESS;
1936
}
1937
/* update WMM, ERP in the beacon */
1938
/* todo: the timer is used instead of the number of the beacon received */
1939
if ((sta_rx_pkts(psta) & 0xf) == 0) {
1940
/* RTW_INFO("update_bcn_info\n"); */
1941
update_beacon_info(padapter, pframe, len, psta);
1942
}
1943
1944
pmlmepriv->cur_network_scanned->network.Rssi = precv_frame->u.hdr.attrib.phy_info.recv_signal_power;
1945
pmlmeext->bcn_cnt++;
1946
#ifdef CONFIG_BCN_RECV_TIME
1947
rtw_rx_bcn_time_update(padapter, len, precv_frame->u.hdr.attrib.data_rate);
1948
#endif
1949
#ifdef CONFIG_TDLS
1950
#ifdef CONFIG_TDLS_CH_SW
1951
if (rtw_tdls_is_chsw_allowed(padapter) == _TRUE) {
1952
/* Send TDLS Channel Switch Request when receiving Beacon */
1953
if ((padapter->tdlsinfo.chsw_info.ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) && (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE)
1954
&& (pmlmeext->cur_channel == rtw_get_oper_ch(padapter))) {
1955
ptdls_sta = rtw_get_stainfo(&padapter->stapriv, padapter->tdlsinfo.chsw_info.addr);
1956
if (ptdls_sta != NULL) {
1957
if (ptdls_sta->tdls_sta_state | TDLS_LINKED_STATE)
1958
_set_timer(&ptdls_sta->stay_on_base_chnl_timer, TDLS_CH_SW_STAY_ON_BASE_CHNL_TIMEOUT);
1959
}
1960
}
1961
}
1962
#endif
1963
#endif /* CONFIG_TDLS */
1964
1965
#ifdef CONFIG_DFS
1966
process_csa_ie(padapter
1967
, pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_
1968
, len - (WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_));
1969
#endif
1970
1971
#ifdef CONFIG_P2P_PS
1972
process_p2p_ps_ie(padapter, (pframe + WLAN_HDR_A3_LEN), (len - WLAN_HDR_A3_LEN));
1973
#endif /* CONFIG_P2P_PS */
1974
1975
if (pmlmeext->tsf_update_required && pmlmeext->en_hw_update_tsf)
1976
rtw_enable_hw_update_tsf_cmd(padapter);
1977
1978
#if 0 /* move to validate_recv_mgnt_frame */
1979
psta->sta_stats.rx_mgnt_pkts++;
1980
#endif
1981
}
1982
1983
} else if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
1984
u8 rate_set[16];
1985
u8 rate_num = 0;
1986
1987
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
1988
if (psta != NULL) {
1989
/*
1990
* update WMM, ERP in the beacon
1991
* todo: the timer is used instead of the number of the beacon received
1992
*/
1993
if ((sta_rx_pkts(psta) & 0xf) == 0)
1994
update_beacon_info(padapter, pframe, len, psta);
1995
1996
if (pmlmeext->tsf_update_required && pmlmeext->en_hw_update_tsf)
1997
rtw_enable_hw_update_tsf_cmd(padapter);
1998
} else {
1999
rtw_ies_get_supported_rate(pframe + WLAN_HDR_A3_LEN + _BEACON_IE_OFFSET_, len - WLAN_HDR_A3_LEN - _BEACON_IE_OFFSET_, rate_set, &rate_num);
2000
if (rate_num == 0) {
2001
RTW_INFO(FUNC_ADPT_FMT" RX beacon with no supported rate\n", FUNC_ADPT_ARG(padapter));
2002
goto _END_ONBEACON_;
2003
}
2004
2005
psta = rtw_alloc_stainfo(pstapriv, get_addr2_ptr(pframe));
2006
if (psta == NULL) {
2007
RTW_INFO(FUNC_ADPT_FMT" Exceed the upper limit of supported clients\n", FUNC_ADPT_ARG(padapter));
2008
goto _END_ONBEACON_;
2009
}
2010
2011
psta->expire_to = pstapriv->adhoc_expire_to;
2012
2013
_rtw_memcpy(psta->bssrateset, rate_set, rate_num);
2014
psta->bssratelen = rate_num;
2015
2016
/* update TSF Value */
2017
update_TSF(pmlmeext, pframe, len);
2018
2019
/* report sta add event */
2020
report_add_sta_event(padapter, get_addr2_ptr(pframe));
2021
}
2022
}
2023
}
2024
2025
_END_ONBEACON_:
2026
2027
return _SUCCESS;
2028
2029
}
2030
2031
unsigned int OnAuth(_adapter *padapter, union recv_frame *precv_frame)
2032
{
2033
#ifdef CONFIG_AP_MODE
2034
_irqL irqL;
2035
unsigned int auth_mode, seq, ie_len;
2036
unsigned char *sa, *p;
2037
u16 algorithm;
2038
int status;
2039
static struct sta_info stat;
2040
struct sta_info *pstat = NULL;
2041
struct sta_priv *pstapriv = &padapter->stapriv;
2042
struct security_priv *psecuritypriv = &padapter->securitypriv;
2043
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2044
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2045
u8 *pframe = precv_frame->u.hdr.rx_data;
2046
uint len = precv_frame->u.hdr.len;
2047
u8 offset = 0;
2048
2049
2050
#ifdef CONFIG_CONCURRENT_MODE
2051
if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2052
rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) {
2053
/* don't process auth request; */
2054
return _SUCCESS;
2055
}
2056
#endif /* CONFIG_CONCURRENT_MODE */
2057
2058
if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2059
return _FAIL;
2060
2061
if (!MLME_IS_ASOC(padapter))
2062
return _SUCCESS;
2063
2064
#if defined(CONFIG_IOCTL_CFG80211) && defined(CONFIG_RTW_MESH)
2065
if (MLME_IS_MESH(padapter))
2066
return rtw_mesh_on_auth(padapter, precv_frame);
2067
#endif
2068
2069
RTW_INFO("+OnAuth\n");
2070
2071
sa = get_addr2_ptr(pframe);
2072
2073
auth_mode = psecuritypriv->dot11AuthAlgrthm;
2074
2075
if (GetPrivacy(pframe)) {
2076
u8 *iv;
2077
struct rx_pkt_attrib *prxattrib = &(precv_frame->u.hdr.attrib);
2078
2079
prxattrib->hdrlen = WLAN_HDR_A3_LEN;
2080
prxattrib->encrypt = _WEP40_;
2081
2082
iv = pframe + prxattrib->hdrlen;
2083
prxattrib->key_index = ((iv[3] >> 6) & 0x3);
2084
2085
prxattrib->iv_len = 4;
2086
prxattrib->icv_len = 4;
2087
2088
rtw_wep_decrypt(padapter, (u8 *)precv_frame);
2089
2090
offset = 4;
2091
}
2092
2093
algorithm = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2094
seq = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2095
2096
RTW_INFO("auth alg=%x, seq=%X\n", algorithm, seq);
2097
2098
if (rtw_ap_linking_test_force_auth_fail()) {
2099
status = rtw_ap_linking_test_force_auth_fail();
2100
RTW_INFO(FUNC_ADPT_FMT" force auth fail with status:%u\n"
2101
, FUNC_ADPT_ARG(padapter), status);
2102
goto auth_fail;
2103
}
2104
2105
if ((auth_mode == 2) && (algorithm != WLAN_AUTH_SAE) &&
2106
(psecuritypriv->dot11PrivacyAlgrthm != _WEP40_) &&
2107
(psecuritypriv->dot11PrivacyAlgrthm != _WEP104_))
2108
auth_mode = 0;
2109
2110
if ((algorithm > 0 && auth_mode == 0) || /* rx a shared-key auth but shared not enabled */
2111
(algorithm == 0 && auth_mode == 1)) { /* rx a open-system auth but shared-key is enabled */
2112
RTW_INFO("auth rejected due to bad alg [alg=%d, auth_mib=%d] %02X%02X%02X%02X%02X%02X\n",
2113
algorithm, auth_mode, sa[0], sa[1], sa[2], sa[3], sa[4], sa[5]);
2114
2115
status = _STATS_NO_SUPP_ALG_;
2116
2117
goto auth_fail;
2118
}
2119
2120
#if CONFIG_RTW_MACADDR_ACL
2121
if (rtw_access_ctrl(padapter, sa) == _FALSE) {
2122
status = _STATS_UNABLE_HANDLE_STA_;
2123
goto auth_fail;
2124
}
2125
#endif
2126
2127
pstat = rtw_get_stainfo(pstapriv, sa);
2128
if (pstat == NULL) {
2129
2130
/* allocate a new one */
2131
RTW_INFO("going to alloc stainfo for sa="MAC_FMT"\n", MAC_ARG(sa));
2132
pstat = rtw_alloc_stainfo(pstapriv, sa);
2133
if (pstat == NULL) {
2134
RTW_INFO(" Exceed the upper limit of supported clients...\n");
2135
status = _STATS_UNABLE_HANDLE_STA_;
2136
goto auth_fail;
2137
}
2138
2139
pstat->state = WIFI_FW_AUTH_NULL;
2140
pstat->auth_seq = 0;
2141
2142
/* pstat->flags = 0; */
2143
/* pstat->capability = 0; */
2144
} else {
2145
#ifdef CONFIG_IEEE80211W
2146
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2147
|| !(pstat->flags & WLAN_STA_MFP))
2148
#endif /* CONFIG_IEEE80211W */
2149
{
2150
2151
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2152
if (rtw_is_list_empty(&pstat->asoc_list) == _FALSE) {
2153
rtw_list_delete(&pstat->asoc_list);
2154
pstapriv->asoc_list_cnt--;
2155
if (pstat->expire_to > 0)
2156
;/* TODO: STA re_auth within expire_to */
2157
}
2158
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2159
2160
if (seq == 1)
2161
; /* TODO: STA re_auth and auth timeout */
2162
2163
}
2164
}
2165
2166
#ifdef CONFIG_IEEE80211W
2167
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2168
|| !(pstat->flags & WLAN_STA_MFP))
2169
#endif /* CONFIG_IEEE80211W */
2170
{
2171
_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2172
if (rtw_is_list_empty(&pstat->auth_list)) {
2173
2174
rtw_list_insert_tail(&pstat->auth_list, &pstapriv->auth_list);
2175
pstapriv->auth_list_cnt++;
2176
}
2177
_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2178
}
2179
2180
if (pstat->auth_seq == 0)
2181
pstat->expire_to = pstapriv->auth_to;
2182
2183
#ifdef CONFIG_IOCTL_CFG80211
2184
if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
2185
if ((algorithm == WLAN_AUTH_SAE) &&
2186
(auth_mode == dot11AuthAlgrthm_8021X)) {
2187
pstat->authalg = algorithm;
2188
2189
rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
2190
return _SUCCESS;
2191
}
2192
}
2193
#endif /* CONFIG_IOCTL_CFG80211 */
2194
2195
if ((pstat->auth_seq + 1) != seq) {
2196
RTW_INFO("(1)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2197
seq, pstat->auth_seq + 1);
2198
status = _STATS_OUT_OF_AUTH_SEQ_;
2199
goto auth_fail;
2200
}
2201
2202
if (algorithm == 0 && (auth_mode == 0 || auth_mode == 2 || auth_mode == 3)) {
2203
if (seq == 1) {
2204
#ifdef CONFIG_IEEE80211W
2205
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2206
|| !(pstat->flags & WLAN_STA_MFP))
2207
#endif /* CONFIG_IEEE80211W */
2208
{
2209
pstat->state &= ~WIFI_FW_AUTH_NULL;
2210
pstat->state |= WIFI_FW_AUTH_SUCCESS;
2211
pstat->expire_to = pstapriv->assoc_to;
2212
}
2213
pstat->authalg = algorithm;
2214
} else {
2215
RTW_INFO("(2)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2216
seq, pstat->auth_seq + 1);
2217
status = _STATS_OUT_OF_AUTH_SEQ_;
2218
goto auth_fail;
2219
}
2220
} else { /* shared system or auto authentication */
2221
if (seq == 1) {
2222
/* prepare for the challenging txt... */
2223
2224
/* get_random_bytes((void *)pstat->chg_txt, 128); */ /* TODO: */
2225
_rtw_memset((void *)pstat->chg_txt, 78, 128);
2226
#ifdef CONFIG_IEEE80211W
2227
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2228
|| !(pstat->flags & WLAN_STA_MFP))
2229
#endif /* CONFIG_IEEE80211W */
2230
{
2231
pstat->state &= ~WIFI_FW_AUTH_NULL;
2232
pstat->state |= WIFI_FW_AUTH_STATE;
2233
}
2234
pstat->authalg = algorithm;
2235
pstat->auth_seq = 2;
2236
} else if (seq == 3) {
2237
/* checking for challenging txt... */
2238
RTW_INFO("checking for challenging txt...\n");
2239
2240
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + 4 + _AUTH_IE_OFFSET_ , _CHLGETXT_IE_, (int *)&ie_len,
2241
len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_ - 4);
2242
2243
if ((p == NULL) || (ie_len <= 0)) {
2244
RTW_INFO("auth rejected because challenge failure!(1)\n");
2245
status = _STATS_CHALLENGE_FAIL_;
2246
goto auth_fail;
2247
}
2248
2249
if (_rtw_memcmp((void *)(p + 2), pstat->chg_txt, 128)) {
2250
#ifdef CONFIG_IEEE80211W
2251
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2252
|| !(pstat->flags & WLAN_STA_MFP))
2253
#endif /* CONFIG_IEEE80211W */
2254
{
2255
pstat->state &= (~WIFI_FW_AUTH_STATE);
2256
pstat->state |= WIFI_FW_AUTH_SUCCESS;
2257
/* challenging txt is correct... */
2258
pstat->expire_to = pstapriv->assoc_to;
2259
}
2260
} else {
2261
RTW_INFO("auth rejected because challenge failure!\n");
2262
status = _STATS_CHALLENGE_FAIL_;
2263
goto auth_fail;
2264
}
2265
} else {
2266
RTW_INFO("(3)auth rejected because out of seq [rx_seq=%d, exp_seq=%d]!\n",
2267
seq, pstat->auth_seq + 1);
2268
status = _STATS_OUT_OF_AUTH_SEQ_;
2269
goto auth_fail;
2270
}
2271
}
2272
2273
2274
/* Now, we are going to issue_auth... */
2275
pstat->auth_seq = seq + 1;
2276
2277
#ifdef CONFIG_NATIVEAP_MLME
2278
issue_auth(padapter, pstat, (unsigned short)(_STATS_SUCCESSFUL_));
2279
#endif
2280
2281
if ((pstat->state & WIFI_FW_AUTH_SUCCESS) || (pstat->state & WIFI_FW_ASSOC_SUCCESS))
2282
pstat->auth_seq = 0;
2283
2284
2285
return _SUCCESS;
2286
2287
auth_fail:
2288
2289
if (pstat)
2290
rtw_free_stainfo(padapter , pstat);
2291
2292
pstat = &stat;
2293
_rtw_memset((char *)pstat, '\0', sizeof(stat));
2294
pstat->auth_seq = 2;
2295
_rtw_memcpy(pstat->cmn.mac_addr, sa, ETH_ALEN);
2296
2297
#ifdef CONFIG_NATIVEAP_MLME
2298
issue_auth(padapter, pstat, (unsigned short)status);
2299
#endif
2300
2301
#endif
2302
return _FAIL;
2303
2304
}
2305
2306
unsigned int OnAuthClient(_adapter *padapter, union recv_frame *precv_frame)
2307
{
2308
unsigned int seq, len, status, algthm, offset;
2309
unsigned char *p;
2310
unsigned int go2asoc = 0;
2311
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2312
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2313
u8 *pframe = precv_frame->u.hdr.rx_data;
2314
uint pkt_len = precv_frame->u.hdr.len;
2315
2316
RTW_INFO("%s\n", __FUNCTION__);
2317
2318
#ifdef CONFIG_IOCTL_CFG80211
2319
if (GET_CFG80211_REPORT_MGMT(adapter_wdev_data(padapter), IEEE80211_STYPE_AUTH) == _TRUE) {
2320
if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) {
2321
if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
2322
RTW_INFO("SAE: PMKSA cache entry found\n");
2323
goto normal;
2324
}
2325
rtw_cfg80211_rx_mframe(padapter, precv_frame, NULL);
2326
return _SUCCESS;
2327
}
2328
}
2329
2330
normal:
2331
#endif /* CONFIG_IOCTL_CFG80211 */
2332
2333
/* check A1 matches or not */
2334
if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2335
return _SUCCESS;
2336
2337
if (!(pmlmeinfo->state & WIFI_FW_AUTH_STATE) || pmlmeext->join_abort)
2338
return _SUCCESS;
2339
2340
offset = (GetPrivacy(pframe)) ? 4 : 0;
2341
2342
algthm = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset));
2343
seq = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 2));
2344
status = le16_to_cpu(*(unsigned short *)((SIZE_PTR)pframe + WLAN_HDR_A3_LEN + offset + 4));
2345
2346
if (status != 0) {
2347
RTW_INFO("clnt auth fail, status: %d\n", status);
2348
if (status == 13) { /* && pmlmeinfo->auth_algo == dot11AuthAlgrthm_Auto) */
2349
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2350
pmlmeinfo->auth_algo = dot11AuthAlgrthm_Open;
2351
else
2352
pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared;
2353
/* pmlmeinfo->reauth_count = 0; */
2354
}
2355
2356
pmlmeinfo->auth_status = status;
2357
set_link_timer(pmlmeext, 1);
2358
goto authclnt_fail;
2359
}
2360
2361
if (seq == 2) {
2362
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) {
2363
/* legendary shared system */
2364
p = rtw_get_ie(pframe + WLAN_HDR_A3_LEN + _AUTH_IE_OFFSET_, _CHLGETXT_IE_, (int *)&len,
2365
pkt_len - WLAN_HDR_A3_LEN - _AUTH_IE_OFFSET_);
2366
2367
if (p == NULL) {
2368
/* RTW_INFO("marc: no challenge text?\n"); */
2369
goto authclnt_fail;
2370
}
2371
2372
_rtw_memcpy((void *)(pmlmeinfo->chg_txt), (void *)(p + 2), len);
2373
pmlmeinfo->auth_seq = 3;
2374
issue_auth(padapter, NULL, 0);
2375
set_link_timer(pmlmeext, REAUTH_TO);
2376
2377
return _SUCCESS;
2378
} else {
2379
/* open, or 802.11r FTAA system */
2380
go2asoc = 1;
2381
}
2382
} else if (seq == 4) {
2383
if (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared)
2384
go2asoc = 1;
2385
else
2386
goto authclnt_fail;
2387
} else {
2388
/* this is also illegal */
2389
/* RTW_INFO("marc: clnt auth failed due to illegal seq=%x\n", seq); */
2390
goto authclnt_fail;
2391
}
2392
2393
if (go2asoc) {
2394
#ifdef CONFIG_RTW_80211R
2395
if (rtw_ft_update_auth_rsp_ies(padapter, pframe, pkt_len))
2396
return _SUCCESS;
2397
#endif
2398
RTW_PRINT("auth success, start assoc\n");
2399
start_clnt_assoc(padapter);
2400
return _SUCCESS;
2401
}
2402
2403
authclnt_fail:
2404
2405
/* pmlmeinfo->state &= ~(WIFI_FW_AUTH_STATE); */
2406
2407
return _FAIL;
2408
2409
}
2410
2411
unsigned int OnAssocReq(_adapter *padapter, union recv_frame *precv_frame)
2412
{
2413
#ifdef CONFIG_AP_MODE
2414
_irqL irqL;
2415
u16 listen_interval;
2416
struct rtw_ieee802_11_elems elems;
2417
struct sta_info *pstat;
2418
unsigned char reassoc, *pos;
2419
int left;
2420
unsigned short status = _STATS_SUCCESSFUL_;
2421
unsigned short frame_type, ie_offset = 0;
2422
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2423
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2424
WLAN_BSSID_EX *cur = &(pmlmeinfo->network);
2425
struct sta_priv *pstapriv = &padapter->stapriv;
2426
u8 *pframe = precv_frame->u.hdr.rx_data;
2427
uint pkt_len = precv_frame->u.hdr.len;
2428
#ifdef CONFIG_P2P
2429
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2430
u8 p2p_status_code = P2P_STATUS_SUCCESS;
2431
u8 *p2pie;
2432
u32 p2pielen = 0;
2433
#endif /* CONFIG_P2P */
2434
2435
#ifdef CONFIG_CONCURRENT_MODE
2436
if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) &&
2437
rtw_mi_buddy_check_fwstate(padapter, _FW_UNDER_LINKING | _FW_UNDER_SURVEY)) {
2438
/* don't process assoc request; */
2439
return _SUCCESS;
2440
}
2441
#endif /* CONFIG_CONCURRENT_MODE */
2442
2443
if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
2444
return _FAIL;
2445
2446
frame_type = get_frame_sub_type(pframe);
2447
if (frame_type == WIFI_ASSOCREQ) {
2448
reassoc = 0;
2449
ie_offset = _ASOCREQ_IE_OFFSET_;
2450
} else { /* WIFI_REASSOCREQ */
2451
reassoc = 1;
2452
ie_offset = _REASOCREQ_IE_OFFSET_;
2453
}
2454
2455
2456
if (pkt_len < IEEE80211_3ADDR_LEN + ie_offset) {
2457
RTW_INFO("handle_assoc(reassoc=%d) - too short payload (len=%lu)"
2458
"\n", reassoc, (unsigned long)pkt_len);
2459
return _FAIL;
2460
}
2461
2462
pstat = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2463
if (pstat == (struct sta_info *)NULL) {
2464
status = _RSON_CLS2_;
2465
goto asoc_class2_error;
2466
}
2467
2468
RTW_INFO("%s\n", __FUNCTION__);
2469
2470
if (pstat->authalg == WLAN_AUTH_SAE) {
2471
/* WPA3-SAE */
2472
if (((pstat->state) & WIFI_FW_AUTH_NULL)) {
2473
/* TODO:
2474
Queue AssocReq and Proccess
2475
by external auth trigger. */
2476
RTW_INFO("%s: wait external auth trigger\n", __func__);
2477
return _SUCCESS;
2478
}
2479
}
2480
2481
/* check if this stat has been successfully authenticated/assocated */
2482
if (!((pstat->state) & WIFI_FW_AUTH_SUCCESS)) {
2483
if (!((pstat->state) & WIFI_FW_ASSOC_SUCCESS)) {
2484
status = _RSON_CLS2_;
2485
goto asoc_class2_error;
2486
} else {
2487
pstat->state &= (~WIFI_FW_ASSOC_SUCCESS);
2488
pstat->state |= WIFI_FW_ASSOC_STATE;
2489
}
2490
} else {
2491
pstat->state &= (~WIFI_FW_AUTH_SUCCESS);
2492
pstat->state |= WIFI_FW_ASSOC_STATE;
2493
}
2494
2495
#if 0/* todo:tkip_countermeasures */
2496
if (hapd->tkip_countermeasures) {
2497
resp = WLAN_REASON_MICHAEL_MIC_FAILURE;
2498
goto fail;
2499
}
2500
#endif
2501
2502
if (rtw_ap_linking_test_force_asoc_fail()) {
2503
status = rtw_ap_linking_test_force_asoc_fail();
2504
RTW_INFO(FUNC_ADPT_FMT" force asoc fail with status:%u\n"
2505
, FUNC_ADPT_ARG(padapter), status);
2506
goto OnAssocReqFail;
2507
}
2508
2509
/* now parse all ieee802_11 ie to point to elems */
2510
left = pkt_len - (IEEE80211_3ADDR_LEN + ie_offset);
2511
pos = pframe + (IEEE80211_3ADDR_LEN + ie_offset);
2512
if (rtw_ieee802_11_parse_elems(pos, left, &elems, 1) == ParseFailed) {
2513
RTW_INFO("STA " MAC_FMT " sent invalid association request\n",
2514
MAC_ARG(pstat->cmn.mac_addr));
2515
status = _STATS_FAILURE_;
2516
goto OnAssocReqFail;
2517
}
2518
2519
rtw_ap_parse_sta_capability(padapter, pstat, pframe + WLAN_HDR_A3_LEN);
2520
2521
listen_interval = RTW_GET_LE16(pframe + WLAN_HDR_A3_LEN + 2);
2522
#if 0/* todo: */
2523
/* check listen_interval */
2524
if (listen_interval > hapd->conf->max_listen_interval) {
2525
hostapd_logger(hapd, mgmt->sa, HOSTAPD_MODULE_IEEE80211,
2526
HOSTAPD_LEVEL_DEBUG,
2527
"Too large Listen Interval (%d)",
2528
listen_interval);
2529
resp = WLAN_STATUS_ASSOC_DENIED_LISTEN_INT_TOO_LARGE;
2530
goto fail;
2531
}
2532
2533
pstat->listen_interval = listen_interval;
2534
#endif
2535
2536
/* now we should check all the fields... */
2537
/* checking SSID */
2538
if (elems.ssid == NULL
2539
|| elems.ssid_len == 0
2540
|| elems.ssid_len != cur->Ssid.SsidLength
2541
|| _rtw_memcmp(elems.ssid, cur->Ssid.Ssid, cur->Ssid.SsidLength) == _FALSE
2542
) {
2543
status = _STATS_FAILURE_;
2544
goto OnAssocReqFail;
2545
}
2546
2547
/* (Extended) Supported rates */
2548
status = rtw_ap_parse_sta_supported_rates(padapter, pstat
2549
, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2550
if (status != _STATS_SUCCESSFUL_)
2551
goto OnAssocReqFail;
2552
2553
/* check RSN/WPA/WPS */
2554
status = rtw_ap_parse_sta_security_ie(padapter, pstat, &elems);
2555
if (status != _STATS_SUCCESSFUL_)
2556
goto OnAssocReqFail;
2557
2558
/* check if there is WMM IE & support WWM-PS */
2559
rtw_ap_parse_sta_wmm_ie(padapter, pstat
2560
, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2561
2562
#ifdef CONFIG_RTS_FULL_BW
2563
/*check vendor IE*/
2564
rtw_parse_sta_vendor_ie_8812(padapter, pstat
2565
, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset);
2566
#endif/*CONFIG_RTS_FULL_BW*/
2567
2568
rtw_ap_parse_sta_ht_ie(padapter, pstat, &elems);
2569
rtw_ap_parse_sta_vht_ie(padapter, pstat, &elems);
2570
2571
if (((pstat->flags & WLAN_STA_HT) || (pstat->flags & WLAN_STA_VHT)) &&
2572
((pstat->wpa2_pairwise_cipher & WPA_CIPHER_TKIP) ||
2573
(pstat->wpa_pairwise_cipher & WPA_CIPHER_TKIP))) {
2574
2575
RTW_INFO("(V)HT: " MAC_FMT " tried to use TKIP with (V)HT association\n", MAC_ARG(pstat->cmn.mac_addr));
2576
2577
pstat->flags &= ~WLAN_STA_HT;
2578
pstat->flags &= ~WLAN_STA_VHT;
2579
/*status = WLAN_STATUS_CIPHER_REJECTED_PER_POLICY;
2580
* goto OnAssocReqFail;
2581
*/
2582
}
2583
2584
#ifdef CONFIG_P2P
2585
pstat->is_p2p_device = _FALSE;
2586
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
2587
p2pie = rtw_get_p2p_ie(pframe + WLAN_HDR_A3_LEN + ie_offset , pkt_len - WLAN_HDR_A3_LEN - ie_offset , NULL, &p2pielen);
2588
if (p2pie) {
2589
pstat->is_p2p_device = _TRUE;
2590
p2p_status_code = (u8)process_assoc_req_p2p_ie(pwdinfo, pframe, pkt_len, pstat);
2591
if (p2p_status_code > 0) {
2592
pstat->p2p_status_code = p2p_status_code;
2593
status = _STATS_CAP_FAIL_;
2594
goto OnAssocReqFail;
2595
}
2596
}
2597
#ifdef CONFIG_WFD
2598
rtw_process_wfd_ies(padapter, pframe + WLAN_HDR_A3_LEN + ie_offset, pkt_len - WLAN_HDR_A3_LEN - ie_offset, __func__);
2599
#endif
2600
}
2601
pstat->p2p_status_code = p2p_status_code;
2602
#endif /* CONFIG_P2P */
2603
2604
#ifdef CONFIG_RTW_REPEATER_SON
2605
if (rtw_rson_ap_check_sta(padapter, pframe, pkt_len, ie_offset))
2606
goto OnAssocReqFail;
2607
#endif
2608
2609
/* TODO: identify_proprietary_vendor_ie(); */
2610
/* Realtek proprietary IE */
2611
/* identify if this is Broadcom sta */
2612
/* identify if this is ralink sta */
2613
/* Customer proprietary IE */
2614
2615
#ifdef CONFIG_RTW_80211K
2616
rtw_ap_parse_sta_rm_en_cap(padapter, pstat, &elems);
2617
#endif
2618
2619
/* AID assignment */
2620
if (pstat->cmn.aid > 0)
2621
RTW_INFO(FUNC_ADPT_FMT" old AID=%d\n", FUNC_ADPT_ARG(padapter), pstat->cmn.aid);
2622
else {
2623
if (!rtw_aid_alloc(padapter, pstat)) {
2624
RTW_INFO(FUNC_ADPT_FMT" no room for more AIDs\n", FUNC_ADPT_ARG(padapter));
2625
status = WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA;
2626
goto OnAssocReqFail;
2627
}
2628
RTW_INFO(FUNC_ADPT_FMT" allocate new AID=%d\n", FUNC_ADPT_ARG(padapter), pstat->cmn.aid);
2629
}
2630
2631
pstat->state &= (~WIFI_FW_ASSOC_STATE);
2632
pstat->state |= WIFI_FW_ASSOC_SUCCESS;
2633
/* RTW_INFO("==================%s, %d, (%x), bpairwise_key_installed=%d, MAC:"MAC_FMT"\n"
2634
, __func__, __LINE__, pstat->state, pstat->bpairwise_key_installed, MAC_ARG(pstat->cmn.mac_addr)); */
2635
#ifdef CONFIG_IEEE80211W
2636
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2637
|| !(pstat->flags & WLAN_STA_MFP))
2638
#endif /* CONFIG_IEEE80211W */
2639
{
2640
_enter_critical_bh(&pstapriv->auth_list_lock, &irqL);
2641
if (!rtw_is_list_empty(&pstat->auth_list)) {
2642
rtw_list_delete(&pstat->auth_list);
2643
pstapriv->auth_list_cnt--;
2644
}
2645
_exit_critical_bh(&pstapriv->auth_list_lock, &irqL);
2646
2647
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2648
if (rtw_is_list_empty(&pstat->asoc_list)) {
2649
pstat->expire_to = pstapriv->expire_to;
2650
rtw_list_insert_tail(&pstat->asoc_list, &pstapriv->asoc_list);
2651
pstapriv->asoc_list_cnt++;
2652
}
2653
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2654
}
2655
2656
/* now the station is qualified to join our BSS... */
2657
if (pstat && (pstat->state & WIFI_FW_ASSOC_SUCCESS) && (_STATS_SUCCESSFUL_ == status)) {
2658
#ifdef CONFIG_NATIVEAP_MLME
2659
#ifdef CONFIG_IEEE80211W
2660
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2661
|| !(pstat->flags & WLAN_STA_MFP))
2662
#endif /* CONFIG_IEEE80211W */
2663
{
2664
/* .1 bss_cap_update & sta_info_update */
2665
bss_cap_update_on_sta_join(padapter, pstat);
2666
sta_info_update(padapter, pstat);
2667
}
2668
#ifdef CONFIG_IEEE80211W
2669
if (pstat->bpairwise_key_installed == _TRUE && (pstat->flags & WLAN_STA_MFP))
2670
status = _STATS_REFUSED_TEMPORARILY_;
2671
#endif /* CONFIG_IEEE80211W */
2672
/* .2 issue assoc rsp before notify station join event. */
2673
if (frame_type == WIFI_ASSOCREQ)
2674
issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2675
else
2676
issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2677
2678
#ifdef CONFIG_IOCTL_CFG80211
2679
_enter_critical_bh(&pstat->lock, &irqL);
2680
if (pstat->passoc_req) {
2681
rtw_mfree(pstat->passoc_req, pstat->assoc_req_len);
2682
pstat->passoc_req = NULL;
2683
pstat->assoc_req_len = 0;
2684
}
2685
2686
pstat->passoc_req = rtw_zmalloc(pkt_len);
2687
if (pstat->passoc_req) {
2688
_rtw_memcpy(pstat->passoc_req, pframe, pkt_len);
2689
pstat->assoc_req_len = pkt_len;
2690
}
2691
_exit_critical_bh(&pstat->lock, &irqL);
2692
#endif /* CONFIG_IOCTL_CFG80211 */
2693
#ifdef CONFIG_IEEE80211W
2694
if ((pstat->bpairwise_key_installed != _TRUE && (pstat->flags & WLAN_STA_MFP))
2695
|| !(pstat->flags & WLAN_STA_MFP))
2696
#endif /* CONFIG_IEEE80211W */
2697
{
2698
/* .3-(1) report sta add event */
2699
report_add_sta_event(padapter, pstat->cmn.mac_addr);
2700
}
2701
#ifdef CONFIG_IEEE80211W
2702
if (pstat->bpairwise_key_installed == _TRUE && (pstat->flags & WLAN_STA_MFP)) {
2703
RTW_INFO(MAC_FMT"\n", MAC_ARG(pstat->cmn.mac_addr));
2704
issue_action_SA_Query(padapter, pstat->cmn.mac_addr, 0, 0, IEEE80211W_RIGHT_KEY);
2705
}
2706
#endif /* CONFIG_IEEE80211W */
2707
#endif /* CONFIG_NATIVEAP_MLME */
2708
}
2709
2710
return _SUCCESS;
2711
2712
asoc_class2_error:
2713
2714
#ifdef CONFIG_NATIVEAP_MLME
2715
issue_deauth(padapter, (void *)get_addr2_ptr(pframe), status);
2716
#endif
2717
2718
return _FAIL;
2719
2720
OnAssocReqFail:
2721
2722
2723
#ifdef CONFIG_NATIVEAP_MLME
2724
pstat->cmn.aid = 0;
2725
if (frame_type == WIFI_ASSOCREQ)
2726
issue_asocrsp(padapter, status, pstat, WIFI_ASSOCRSP);
2727
else
2728
issue_asocrsp(padapter, status, pstat, WIFI_REASSOCRSP);
2729
#endif
2730
2731
2732
#endif /* CONFIG_AP_MODE */
2733
2734
return _FAIL;
2735
2736
}
2737
2738
#if defined(CONFIG_LAYER2_ROAMING) && defined(CONFIG_RTW_80211K)
2739
void rtw_roam_nb_discover(_adapter *padapter, u8 bfroce)
2740
{
2741
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2742
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2743
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2744
struct sta_priv *pstapriv = &padapter->stapriv;
2745
struct sta_info *psta;
2746
u8 nb_req_issue = _FALSE;
2747
2748
if (!check_fwstate(pmlmepriv, _FW_LINKED))
2749
return;
2750
2751
if (!rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE))
2752
return;
2753
2754
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
2755
if (!psta)
2756
return;
2757
2758
if (bfroce || (!pmlmepriv->nb_info.nb_rpt_is_same))
2759
nb_req_issue = _TRUE;
2760
2761
if (nb_req_issue && (psta->rm_en_cap[0] & RTW_RRM_NB_RPT_EN))
2762
rm_add_nb_req(padapter, psta);
2763
}
2764
#endif
2765
2766
unsigned int OnAssocRsp(_adapter *padapter, union recv_frame *precv_frame)
2767
{
2768
uint i;
2769
int res;
2770
unsigned short status;
2771
PNDIS_802_11_VARIABLE_IEs pIE;
2772
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2773
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2774
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2775
/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
2776
u8 *pframe = precv_frame->u.hdr.rx_data;
2777
uint pkt_len = precv_frame->u.hdr.len;
2778
#ifdef CONFIG_WAPI_SUPPORT
2779
PNDIS_802_11_VARIABLE_IEs pWapiIE = NULL;
2780
#endif
2781
2782
RTW_INFO("%s\n", __FUNCTION__);
2783
2784
/* check A1 matches or not */
2785
if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
2786
return _SUCCESS;
2787
2788
if (!(pmlmeinfo->state & (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE)) || pmlmeext->join_abort)
2789
return _SUCCESS;
2790
2791
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
2792
return _SUCCESS;
2793
2794
_cancel_timer_ex(&pmlmeext->link_timer);
2795
2796
/* status */
2797
status = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 2));
2798
if (status > 0) {
2799
RTW_INFO("assoc reject, status code: %d\n", status);
2800
pmlmeinfo->state = WIFI_FW_NULL_STATE;
2801
res = -4;
2802
goto report_assoc_result;
2803
}
2804
2805
/* get capabilities */
2806
pmlmeinfo->capability = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2807
2808
/* set slot time */
2809
pmlmeinfo->slotTime = (pmlmeinfo->capability & BIT(10)) ? 9 : 20;
2810
2811
/* AID */
2812
res = pmlmeinfo->aid = (int)(le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN + 4)) & 0x3fff);
2813
2814
/* check aid value */
2815
if (res < 1 || res > 2007) {
2816
RTW_INFO("assoc reject, aid: %d\n", res);
2817
pmlmeinfo->state = WIFI_FW_NULL_STATE;
2818
res = -4;
2819
goto report_assoc_result;
2820
}
2821
2822
/* following are moved to join event callback function */
2823
/* to handle HT, WMM, rate adaptive, update MAC reg */
2824
/* for not to handle the synchronous IO in the tasklet */
2825
for (i = (6 + WLAN_HDR_A3_LEN); i < pkt_len;) {
2826
pIE = (PNDIS_802_11_VARIABLE_IEs)(pframe + i);
2827
2828
switch (pIE->ElementID) {
2829
case _VENDOR_SPECIFIC_IE_:
2830
if (_rtw_memcmp(pIE->data, WMM_PARA_OUI, 6)) /* WMM */
2831
WMM_param_handler(padapter, pIE);
2832
#if defined(CONFIG_P2P) && defined(CONFIG_WFD)
2833
else if (_rtw_memcmp(pIE->data, WFD_OUI, 4)) /* WFD */
2834
rtw_process_wfd_ie(padapter, (u8 *)pIE, pIE->Length, __func__);
2835
#endif
2836
break;
2837
2838
#ifdef CONFIG_WAPI_SUPPORT
2839
case _WAPI_IE_:
2840
pWapiIE = pIE;
2841
break;
2842
#endif
2843
2844
case _HT_CAPABILITY_IE_: /* HT caps */
2845
HT_caps_handler(padapter, pIE);
2846
#ifdef ROKU_PRIVATE
2847
HT_caps_handler_infra_ap(padapter, pIE);
2848
#endif /* ROKU_PRIVATE */
2849
break;
2850
2851
case _HT_EXTRA_INFO_IE_: /* HT info */
2852
HT_info_handler(padapter, pIE);
2853
break;
2854
2855
#ifdef CONFIG_80211AC_VHT
2856
case EID_VHTCapability:
2857
VHT_caps_handler(padapter, pIE);
2858
#ifdef ROKU_PRIVATE
2859
VHT_caps_handler_infra_ap(padapter, pIE);
2860
#endif /* ROKU_PRIVATE */
2861
break;
2862
2863
case EID_VHTOperation:
2864
VHT_operation_handler(padapter, pIE);
2865
break;
2866
#endif
2867
2868
case _ERPINFO_IE_:
2869
ERP_IE_handler(padapter, pIE);
2870
break;
2871
#ifdef CONFIG_TDLS
2872
case _EXT_CAP_IE_:
2873
if (check_ap_tdls_prohibited(pIE->data, pIE->Length) == _TRUE)
2874
padapter->tdlsinfo.ap_prohibited = _TRUE;
2875
if (check_ap_tdls_ch_switching_prohibited(pIE->data, pIE->Length) == _TRUE)
2876
padapter->tdlsinfo.ch_switch_prohibited = _TRUE;
2877
break;
2878
#endif /* CONFIG_TDLS */
2879
2880
#ifdef CONFIG_RTW_80211K
2881
case _EID_RRM_EN_CAP_IE_:
2882
RM_IE_handler(padapter, pIE);
2883
break;
2884
#endif
2885
2886
#ifdef ROKU_PRIVATE
2887
/* Infra mode, used to store AP's info , Parse the supported rates from AssocRsp */
2888
case _SUPPORTEDRATES_IE_:
2889
Supported_rate_infra_ap(padapter, pIE);
2890
break;
2891
2892
case _EXT_SUPPORTEDRATES_IE_:
2893
Extended_Supported_rate_infra_ap(padapter, pIE);
2894
break;
2895
#endif /* ROKU_PRIVATE */
2896
default:
2897
break;
2898
}
2899
2900
i += (pIE->Length + 2);
2901
}
2902
2903
#ifdef CONFIG_WAPI_SUPPORT
2904
rtw_wapi_on_assoc_ok(padapter, pIE);
2905
#endif
2906
2907
pmlmeinfo->state &= (~WIFI_FW_ASSOC_STATE);
2908
pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
2909
2910
/* Update Basic Rate Table for spec, 2010-12-28 , by thomas */
2911
UpdateBrateTbl(padapter, pmlmeinfo->network.SupportedRates);
2912
2913
report_assoc_result:
2914
if (res > 0)
2915
rtw_buf_update(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len, pframe, pkt_len);
2916
else
2917
rtw_buf_free(&pmlmepriv->assoc_rsp, &pmlmepriv->assoc_rsp_len);
2918
2919
report_join_res(padapter, res, status);
2920
2921
#if defined(CONFIG_LAYER2_ROAMING) && defined(CONFIG_RTW_80211K)
2922
rtw_roam_nb_discover(padapter, _TRUE);
2923
#endif
2924
return _SUCCESS;
2925
}
2926
2927
unsigned int OnDeAuth(_adapter *padapter, union recv_frame *precv_frame)
2928
{
2929
unsigned short reason;
2930
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2931
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2932
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
2933
u8 *pframe = precv_frame->u.hdr.rx_data;
2934
#ifdef CONFIG_P2P
2935
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
2936
#endif /* CONFIG_P2P */
2937
2938
/* check A3 */
2939
if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
2940
return _SUCCESS;
2941
2942
RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
2943
2944
#ifdef CONFIG_P2P
2945
if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
2946
_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
2947
_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
2948
}
2949
#endif /* CONFIG_P2P */
2950
2951
reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
2952
2953
#ifdef CONFIG_AP_MODE
2954
if (MLME_IS_AP(padapter)) {
2955
_irqL irqL;
2956
struct sta_info *psta;
2957
struct sta_priv *pstapriv = &padapter->stapriv;
2958
2959
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2960
/* rtw_free_stainfo(padapter, psta); */
2961
/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
2962
2963
RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
2964
, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
2965
2966
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
2967
if (psta) {
2968
u8 updated = _FALSE;
2969
2970
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2971
if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
2972
rtw_list_delete(&psta->asoc_list);
2973
pstapriv->asoc_list_cnt--;
2974
updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
2975
2976
}
2977
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
2978
2979
associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
2980
}
2981
2982
2983
return _SUCCESS;
2984
} else
2985
#endif
2986
if (!MLME_IS_MESH(padapter)) {
2987
int ignore_received_deauth = 0;
2988
2989
/* Commented by Albert 20130604 */
2990
/* Before sending the auth frame to start the STA/GC mode connection with AP/GO, */
2991
/* we will send the deauth first. */
2992
/* However, the Win8.1 with BRCM Wi-Fi will send the deauth with reason code 6 to us after receieving our deauth. */
2993
/* Added the following code to avoid this case. */
2994
if ((pmlmeinfo->state & WIFI_FW_AUTH_STATE) ||
2995
(pmlmeinfo->state & WIFI_FW_ASSOC_STATE)) {
2996
if (reason == WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA)
2997
ignore_received_deauth = 1;
2998
else if (WLAN_REASON_PREV_AUTH_NOT_VALID == reason) {
2999
/* TODO: 802.11r */
3000
ignore_received_deauth = 1;
3001
}
3002
}
3003
3004
RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM, ignore=%d\n"
3005
, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe), ignore_received_deauth);
3006
3007
if (0 == ignore_received_deauth)
3008
receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3009
}
3010
pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3011
return _SUCCESS;
3012
3013
}
3014
3015
unsigned int OnDisassoc(_adapter *padapter, union recv_frame *precv_frame)
3016
{
3017
unsigned short reason;
3018
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3019
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3020
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3021
u8 *pframe = precv_frame->u.hdr.rx_data;
3022
#ifdef CONFIG_P2P
3023
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3024
#endif /* CONFIG_P2P */
3025
3026
/* check A3 */
3027
if (!(_rtw_memcmp(GetAddr3Ptr(pframe), get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
3028
return _SUCCESS;
3029
3030
RTW_INFO(FUNC_ADPT_FMT" - Start to Disconnect\n", FUNC_ADPT_ARG(padapter));
3031
3032
#ifdef CONFIG_P2P
3033
if (pwdinfo->rx_invitereq_info.scan_op_ch_only) {
3034
_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
3035
_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
3036
}
3037
#endif /* CONFIG_P2P */
3038
3039
reason = le16_to_cpu(*(unsigned short *)(pframe + WLAN_HDR_A3_LEN));
3040
3041
#ifdef CONFIG_AP_MODE
3042
if (MLME_IS_AP(padapter)) {
3043
_irqL irqL;
3044
struct sta_info *psta;
3045
struct sta_priv *pstapriv = &padapter->stapriv;
3046
3047
/* _enter_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3048
/* rtw_free_stainfo(padapter, psta); */
3049
/* _exit_critical_bh(&(pstapriv->sta_hash_lock), &irqL); */
3050
3051
RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3052
, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3053
3054
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3055
if (psta) {
3056
u8 updated = _FALSE;
3057
3058
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3059
if (rtw_is_list_empty(&psta->asoc_list) == _FALSE) {
3060
rtw_list_delete(&psta->asoc_list);
3061
pstapriv->asoc_list_cnt--;
3062
updated = ap_free_sta(padapter, psta, _FALSE, reason, _TRUE);
3063
3064
}
3065
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3066
3067
associated_clients_update(padapter, updated, STA_INFO_UPDATE_ALL);
3068
}
3069
3070
return _SUCCESS;
3071
} else
3072
#endif
3073
if (!MLME_IS_MESH(padapter)) {
3074
RTW_PRINT(FUNC_ADPT_FMT" reason=%u, ta=%pM\n"
3075
, FUNC_ADPT_ARG(padapter), reason, get_addr2_ptr(pframe));
3076
3077
receive_disconnect(padapter, get_addr2_ptr(pframe), reason, _FALSE);
3078
}
3079
pmlmepriv->LinkDetectInfo.bBusyTraffic = _FALSE;
3080
return _SUCCESS;
3081
3082
}
3083
3084
unsigned int OnAtim(_adapter *padapter, union recv_frame *precv_frame)
3085
{
3086
RTW_INFO("%s\n", __FUNCTION__);
3087
return _SUCCESS;
3088
}
3089
3090
unsigned int on_action_spct_ch_switch(_adapter *padapter, struct sta_info *psta, u8 *ies, uint ies_len)
3091
{
3092
unsigned int ret = _FAIL;
3093
struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
3094
struct mlme_ext_info *pmlmeinfo = &(mlmeext->mlmext_info);
3095
3096
if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)) {
3097
ret = _SUCCESS;
3098
goto exit;
3099
}
3100
3101
if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
3102
3103
int ch_switch_mode = -1, ch = -1, ch_switch_cnt = -1;
3104
int ch_offset = -1;
3105
u8 bwmode;
3106
struct ieee80211_info_element *ie;
3107
3108
RTW_INFO(FUNC_NDEV_FMT" from "MAC_FMT"\n",
3109
FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(psta->cmn.mac_addr));
3110
3111
for_each_ie(ie, ies, ies_len) {
3112
if (ie->id == WLAN_EID_CHANNEL_SWITCH) {
3113
ch_switch_mode = ie->data[0];
3114
ch = ie->data[1];
3115
ch_switch_cnt = ie->data[2];
3116
RTW_INFO("ch_switch_mode:%d, ch:%d, ch_switch_cnt:%d\n",
3117
ch_switch_mode, ch, ch_switch_cnt);
3118
} else if (ie->id == WLAN_EID_SECONDARY_CHANNEL_OFFSET) {
3119
ch_offset = secondary_ch_offset_to_hal_ch_offset(ie->data[0]);
3120
RTW_INFO("ch_offset:%d\n", ch_offset);
3121
}
3122
}
3123
3124
if (ch == -1)
3125
return _SUCCESS;
3126
3127
if (ch_offset == -1)
3128
bwmode = mlmeext->cur_bwmode;
3129
else
3130
bwmode = (ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE) ?
3131
CHANNEL_WIDTH_20 : CHANNEL_WIDTH_40;
3132
3133
ch_offset = (ch_offset == -1) ? mlmeext->cur_ch_offset : ch_offset;
3134
3135
/* todo:
3136
* 1. the decision of channel switching
3137
* 2. things after channel switching
3138
*/
3139
3140
ret = rtw_set_chbw_cmd(padapter, ch, bwmode, ch_offset, 0);
3141
}
3142
3143
exit:
3144
return ret;
3145
}
3146
3147
unsigned int on_action_spct(_adapter *padapter, union recv_frame *precv_frame)
3148
{
3149
unsigned int ret = _FAIL;
3150
struct sta_info *psta = NULL;
3151
struct sta_priv *pstapriv = &padapter->stapriv;
3152
u8 *pframe = precv_frame->u.hdr.rx_data;
3153
uint frame_len = precv_frame->u.hdr.len;
3154
u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3155
u8 category;
3156
u8 action;
3157
3158
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
3159
3160
if (!psta)
3161
goto exit;
3162
3163
category = frame_body[0];
3164
if (category != RTW_WLAN_CATEGORY_SPECTRUM_MGMT)
3165
goto exit;
3166
3167
action = frame_body[1];
3168
3169
RTW_INFO(FUNC_ADPT_FMT" action:%u\n", FUNC_ADPT_ARG(padapter), action);
3170
3171
switch (action) {
3172
case RTW_WLAN_ACTION_SPCT_MSR_REQ:
3173
case RTW_WLAN_ACTION_SPCT_MSR_RPRT:
3174
case RTW_WLAN_ACTION_SPCT_TPC_REQ:
3175
case RTW_WLAN_ACTION_SPCT_TPC_RPRT:
3176
break;
3177
case RTW_WLAN_ACTION_SPCT_CHL_SWITCH:
3178
#ifdef CONFIG_SPCT_CH_SWITCH
3179
ret = on_action_spct_ch_switch(padapter, psta
3180
, frame_body + 2, frame_len - (frame_body - pframe) - 2);
3181
#elif defined(CONFIG_DFS)
3182
if (MLME_IS_STA(padapter) && MLME_IS_ASOC(padapter)) {
3183
process_csa_ie(padapter
3184
, frame_body + 2, frame_len - (frame_body - pframe) - 2);
3185
}
3186
#endif
3187
break;
3188
default:
3189
break;
3190
}
3191
3192
exit:
3193
return ret;
3194
}
3195
3196
unsigned int OnAction_qos(_adapter *padapter, union recv_frame *precv_frame)
3197
{
3198
return _SUCCESS;
3199
}
3200
3201
unsigned int OnAction_dls(_adapter *padapter, union recv_frame *precv_frame)
3202
{
3203
return _SUCCESS;
3204
}
3205
3206
#ifdef CONFIG_RTW_WNM
3207
unsigned int on_action_wnm(_adapter *adapter, union recv_frame *rframe)
3208
{
3209
unsigned int ret = _FAIL;
3210
struct sta_info *sta = NULL;
3211
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
3212
struct sta_priv *stapriv = &(adapter->stapriv);
3213
u8 *frame = rframe->u.hdr.rx_data;
3214
u32 frame_len = rframe->u.hdr.len;
3215
u8 *frame_body = (u8 *)(frame + sizeof(struct rtw_ieee80211_hdr_3addr));
3216
u32 frame_body_len = frame_len - sizeof(struct rtw_ieee80211_hdr_3addr);
3217
u8 category, action;
3218
int cnt = 0;
3219
char msg[16];
3220
3221
sta = rtw_get_stainfo(stapriv, get_addr2_ptr(frame));
3222
if (!sta)
3223
goto exit;
3224
3225
category = frame_body[0];
3226
if (category != RTW_WLAN_CATEGORY_WNM)
3227
goto exit;
3228
3229
action = frame_body[1];
3230
3231
switch (action) {
3232
#ifdef CONFIG_RTW_80211R
3233
case RTW_WLAN_ACTION_WNM_BTM_REQ:
3234
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
3235
RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_REQ recv.\n");
3236
rtw_wnm_process_btm_req(adapter, frame_body, frame_body_len);
3237
}
3238
ret = _SUCCESS;
3239
break;
3240
#endif
3241
default:
3242
#ifdef CONFIG_IOCTL_CFG80211
3243
cnt += sprintf((msg + cnt), "ACT_WNM %u", action);
3244
rtw_cfg80211_rx_action(adapter, rframe, msg);
3245
#endif
3246
ret = _SUCCESS;
3247
break;
3248
}
3249
3250
exit:
3251
return ret;
3252
}
3253
#endif /* CONFIG_RTW_WNM */
3254
3255
/**
3256
* rtw_rx_ampdu_size - Get the target RX AMPDU buffer size for the specific @adapter
3257
* @adapter: the adapter to get target RX AMPDU buffer size
3258
*
3259
* Returns: the target RX AMPDU buffer size
3260
*/
3261
u8 rtw_rx_ampdu_size(_adapter *adapter)
3262
{
3263
u8 size;
3264
HT_CAP_AMPDU_FACTOR max_rx_ampdu_factor;
3265
3266
#ifdef CONFIG_BT_COEXIST
3267
if (rtw_btcoex_IsBTCoexCtrlAMPDUSize(adapter) == _TRUE) {
3268
size = rtw_btcoex_GetAMPDUSize(adapter);
3269
goto exit;
3270
}
3271
#endif
3272
3273
/* for scan */
3274
if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3275
&& !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3276
&& adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size != RX_AMPDU_SIZE_INVALID
3277
) {
3278
size = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_size;
3279
goto exit;
3280
}
3281
3282
/* default value based on max_rx_ampdu_factor */
3283
if (adapter->driver_rx_ampdu_factor != 0xFF)
3284
max_rx_ampdu_factor = (HT_CAP_AMPDU_FACTOR)adapter->driver_rx_ampdu_factor;
3285
else
3286
rtw_hal_get_def_var(adapter, HW_VAR_MAX_RX_AMPDU_FACTOR, &max_rx_ampdu_factor);
3287
3288
/* In Maximum A-MPDU Length Exponent subfield of A-MPDU Parameters field of HT Capabilities element,
3289
the unit of max_rx_ampdu_factor are octets. 8K, 16K, 32K, 64K is right.
3290
But the buffer size subfield of Block Ack Parameter Set field in ADDBA action frame indicates
3291
the number of buffers available for this particular TID. Each buffer is equal to max. size of
3292
MSDU or AMSDU.
3293
The size variable means how many MSDUs or AMSDUs, it's not Kbytes.
3294
*/
3295
if (MAX_AMPDU_FACTOR_64K == max_rx_ampdu_factor)
3296
size = 64;
3297
else if (MAX_AMPDU_FACTOR_32K == max_rx_ampdu_factor)
3298
size = 32;
3299
else if (MAX_AMPDU_FACTOR_16K == max_rx_ampdu_factor)
3300
size = 16;
3301
else if (MAX_AMPDU_FACTOR_8K == max_rx_ampdu_factor)
3302
size = 8;
3303
else
3304
size = 64;
3305
3306
exit:
3307
3308
if (size > 127)
3309
size = 127;
3310
3311
return size;
3312
}
3313
3314
/**
3315
* rtw_rx_ampdu_is_accept - Get the permission if RX AMPDU should be set up for the specific @adapter
3316
* @adapter: the adapter to get the permission if RX AMPDU should be set up
3317
*
3318
* Returns: accept or not
3319
*/
3320
bool rtw_rx_ampdu_is_accept(_adapter *adapter)
3321
{
3322
bool accept;
3323
3324
if (adapter->fix_rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID) {
3325
accept = adapter->fix_rx_ampdu_accept;
3326
goto exit;
3327
}
3328
3329
#ifdef CONFIG_BT_COEXIST
3330
if (rtw_btcoex_IsBTCoexRejectAMPDU(adapter) == _TRUE) {
3331
accept = _FALSE;
3332
goto exit;
3333
}
3334
#endif
3335
3336
/* for scan */
3337
if (!mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_DISABLE)
3338
&& !mlmeext_chk_scan_state(&adapter->mlmeextpriv, SCAN_COMPLETE)
3339
&& adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
3340
) {
3341
accept = adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept;
3342
goto exit;
3343
}
3344
3345
/* default value for other cases */
3346
accept = adapter->mlmeextpriv.mlmext_info.bAcceptAddbaReq;
3347
3348
exit:
3349
return accept;
3350
}
3351
3352
/**
3353
* rtw_rx_ampdu_set_size - Set the target RX AMPDU buffer size for the specific @adapter and specific @reason
3354
* @adapter: the adapter to set target RX AMPDU buffer size
3355
* @size: the target RX AMPDU buffer size to set
3356
* @reason: reason for the target RX AMPDU buffer size setting
3357
*
3358
* Returns: whether the target RX AMPDU buffer size is changed
3359
*/
3360
bool rtw_rx_ampdu_set_size(_adapter *adapter, u8 size, u8 reason)
3361
{
3362
bool is_adj = _FALSE;
3363
struct mlme_ext_priv *mlmeext;
3364
struct mlme_ext_info *mlmeinfo;
3365
3366
mlmeext = &adapter->mlmeextpriv;
3367
mlmeinfo = &mlmeext->mlmext_info;
3368
3369
if (reason == RX_AMPDU_DRV_FIXED) {
3370
if (adapter->fix_rx_ampdu_size != size) {
3371
adapter->fix_rx_ampdu_size = size;
3372
is_adj = _TRUE;
3373
RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3374
}
3375
} else if (reason == RX_AMPDU_DRV_SCAN) {
3376
struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
3377
3378
if (ss->rx_ampdu_size != size) {
3379
ss->rx_ampdu_size = size;
3380
is_adj = _TRUE;
3381
RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_size:%u\n", FUNC_ADPT_ARG(adapter), size);
3382
}
3383
}
3384
3385
return is_adj;
3386
}
3387
3388
/**
3389
* rtw_rx_ampdu_set_accept - Set the permission if RX AMPDU should be set up for the specific @adapter and specific @reason
3390
* @adapter: the adapter to set if RX AMPDU should be set up
3391
* @accept: if RX AMPDU should be set up
3392
* @reason: reason for the permission if RX AMPDU should be set up
3393
*
3394
* Returns: whether the permission if RX AMPDU should be set up is changed
3395
*/
3396
bool rtw_rx_ampdu_set_accept(_adapter *adapter, u8 accept, u8 reason)
3397
{
3398
bool is_adj = _FALSE;
3399
struct mlme_ext_priv *mlmeext;
3400
struct mlme_ext_info *mlmeinfo;
3401
3402
mlmeext = &adapter->mlmeextpriv;
3403
mlmeinfo = &mlmeext->mlmext_info;
3404
3405
if (reason == RX_AMPDU_DRV_FIXED) {
3406
if (adapter->fix_rx_ampdu_accept != accept) {
3407
adapter->fix_rx_ampdu_accept = accept;
3408
is_adj = _TRUE;
3409
RTW_INFO(FUNC_ADPT_FMT" fix_rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3410
}
3411
} else if (reason == RX_AMPDU_DRV_SCAN) {
3412
if (adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept != accept) {
3413
adapter->mlmeextpriv.sitesurvey_res.rx_ampdu_accept = accept;
3414
is_adj = _TRUE;
3415
RTW_INFO(FUNC_ADPT_FMT" ss.rx_ampdu_accept:%u\n", FUNC_ADPT_ARG(adapter), accept);
3416
}
3417
}
3418
3419
return is_adj;
3420
}
3421
3422
/**
3423
* rx_ampdu_apply_sta_tid - Apply RX AMPDU setting to the specific @sta and @tid
3424
* @adapter: the adapter to which @sta belongs
3425
* @sta: the sta to be checked
3426
* @tid: the tid to be checked
3427
* @accept: the target permission if RX AMPDU should be set up
3428
* @size: the target RX AMPDU buffer size
3429
*
3430
* Returns:
3431
* 0: no canceled
3432
* 1: canceled by no permission
3433
* 2: canceled by different buffer size
3434
* 3: canceled by potential mismatched status
3435
*
3436
* Blocking function, may sleep
3437
*/
3438
u8 rx_ampdu_apply_sta_tid(_adapter *adapter, struct sta_info *sta, u8 tid, u8 accept, u8 size)
3439
{
3440
u8 ret = 0;
3441
struct recv_reorder_ctrl *reorder_ctl = &sta->recvreorder_ctrl[tid];
3442
3443
if (reorder_ctl->enable == _FALSE) {
3444
if (reorder_ctl->ampdu_size != RX_AMPDU_SIZE_INVALID) {
3445
send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 1);
3446
ret = 3;
3447
}
3448
goto exit;
3449
}
3450
3451
if (accept == _FALSE) {
3452
send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3453
ret = 1;
3454
} else if (reorder_ctl->ampdu_size != size) {
3455
send_delba_sta_tid_wait_ack(adapter, 0, sta, tid, 0);
3456
ret = 2;
3457
}
3458
3459
exit:
3460
return ret;
3461
}
3462
3463
u8 rx_ampdu_size_sta_limit(_adapter *adapter, struct sta_info *sta)
3464
{
3465
u8 sz_limit = 0xFF;
3466
3467
#ifdef CONFIG_80211N_HT
3468
struct registry_priv *regsty = adapter_to_regsty(adapter);
3469
struct mlme_priv *mlme = &adapter->mlmepriv;
3470
struct mlme_ext_info *mlmeinfo = &adapter->mlmeextpriv.mlmext_info;
3471
s8 nss = -1;
3472
u8 bw = rtw_min(sta->cmn.bw_mode, adapter->mlmeextpriv.cur_bwmode);
3473
3474
#ifdef CONFIG_80211AC_VHT
3475
if (is_supported_vht(sta->wireless_mode)) {
3476
nss = rtw_min(rtw_vht_mcsmap_to_nss(mlme->vhtpriv.vht_mcs_map)
3477
, rtw_vht_mcsmap_to_nss(sta->vhtpriv.vht_mcs_map));
3478
} else
3479
#endif
3480
if (is_supported_ht(sta->wireless_mode)) {
3481
nss = rtw_min(rtw_ht_mcsset_to_nss(mlmeinfo->HT_caps.u.HT_cap_element.MCS_rate)
3482
, rtw_ht_mcsset_to_nss(sta->htpriv.ht_cap.supp_mcs_set));
3483
}
3484
3485
if (nss >= 1)
3486
sz_limit = regsty->rx_ampdu_sz_limit_by_nss_bw[nss - 1][bw];
3487
#endif /* CONFIG_80211N_HT */
3488
3489
return sz_limit;
3490
}
3491
3492
/**
3493
* rx_ampdu_apply_sta - Apply RX AMPDU setting to the specific @sta
3494
* @adapter: the adapter to which @sta belongs
3495
* @sta: the sta to be checked
3496
* @accept: the target permission if RX AMPDU should be set up
3497
* @size: the target RX AMPDU buffer size
3498
*
3499
* Returns: number of the RX AMPDU assciation canceled for applying current target setting
3500
*
3501
* Blocking function, may sleep
3502
*/
3503
u8 rx_ampdu_apply_sta(_adapter *adapter, struct sta_info *sta, u8 accept, u8 size)
3504
{
3505
u8 change_cnt = 0;
3506
int i;
3507
3508
for (i = 0; i < TID_NUM; i++) {
3509
if (rx_ampdu_apply_sta_tid(adapter, sta, i, accept, size) != 0)
3510
change_cnt++;
3511
}
3512
3513
return change_cnt;
3514
}
3515
3516
/**
3517
* rtw_rx_ampdu_apply - Apply the current target RX AMPDU setting for the specific @adapter
3518
* @adapter: the adapter to be applied
3519
*
3520
* Returns: number of the RX AMPDU assciation canceled for applying current target setting
3521
*/
3522
u16 rtw_rx_ampdu_apply(_adapter *adapter)
3523
{
3524
u16 adj_cnt = 0;
3525
struct sta_info *sta;
3526
u8 accept = rtw_rx_ampdu_is_accept(adapter);
3527
u8 size;
3528
3529
if (adapter->fix_rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
3530
size = adapter->fix_rx_ampdu_size;
3531
else
3532
size = rtw_rx_ampdu_size(adapter);
3533
3534
if (MLME_IS_STA(adapter)) {
3535
sta = rtw_get_stainfo(&adapter->stapriv, get_bssid(&adapter->mlmepriv));
3536
if (sta) {
3537
u8 sta_size = size;
3538
3539
if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
3540
sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
3541
adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
3542
}
3543
/* TODO: TDLS peer */
3544
3545
} else if (MLME_IS_AP(adapter) || MLME_IS_MESH(adapter)) {
3546
_irqL irqL;
3547
_list *phead, *plist;
3548
u8 peer_num = 0;
3549
char peers[NUM_STA];
3550
struct sta_priv *pstapriv = &adapter->stapriv;
3551
int i;
3552
3553
_enter_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3554
3555
phead = &pstapriv->asoc_list;
3556
plist = get_next(phead);
3557
3558
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
3559
int stainfo_offset;
3560
3561
sta = LIST_CONTAINOR(plist, struct sta_info, asoc_list);
3562
plist = get_next(plist);
3563
3564
stainfo_offset = rtw_stainfo_offset(pstapriv, sta);
3565
if (stainfo_offset_valid(stainfo_offset))
3566
peers[peer_num++] = stainfo_offset;
3567
}
3568
3569
_exit_critical_bh(&pstapriv->asoc_list_lock, &irqL);
3570
3571
for (i = 0; i < peer_num; i++) {
3572
sta = rtw_get_stainfo_by_offset(pstapriv, peers[i]);
3573
if (sta) {
3574
u8 sta_size = size;
3575
3576
if (adapter->fix_rx_ampdu_size == RX_AMPDU_SIZE_INVALID)
3577
sta_size = rtw_min(size, rx_ampdu_size_sta_limit(adapter, sta));
3578
adj_cnt += rx_ampdu_apply_sta(adapter, sta, accept, sta_size);
3579
}
3580
}
3581
}
3582
3583
/* TODO: ADHOC */
3584
3585
return adj_cnt;
3586
}
3587
3588
unsigned int OnAction_back(_adapter *padapter, union recv_frame *precv_frame)
3589
{
3590
u8 *addr;
3591
struct sta_info *psta = NULL;
3592
struct recv_reorder_ctrl *preorder_ctrl;
3593
unsigned char *frame_body;
3594
unsigned char category, action;
3595
unsigned short tid, status, reason_code = 0;
3596
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3597
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3598
u8 *pframe = precv_frame->u.hdr.rx_data;
3599
struct sta_priv *pstapriv = &padapter->stapriv;
3600
struct registry_priv *pregpriv = &padapter->registrypriv;
3601
3602
#ifdef CONFIG_80211N_HT
3603
3604
RTW_INFO("%s\n", __FUNCTION__);
3605
3606
/* check RA matches or not */
3607
if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
3608
return _SUCCESS;
3609
3610
#if 0
3611
/* check A1 matches or not */
3612
if (!_rtw_memcmp(adapter_mac_addr(padapter), get_da(pframe), ETH_ALEN))
3613
return _SUCCESS;
3614
#endif
3615
3616
if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
3617
if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
3618
return _SUCCESS;
3619
3620
addr = get_addr2_ptr(pframe);
3621
psta = rtw_get_stainfo(pstapriv, addr);
3622
3623
if (psta == NULL)
3624
return _SUCCESS;
3625
3626
frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
3627
3628
category = frame_body[0];
3629
if (category == RTW_WLAN_CATEGORY_BACK) { /* representing Block Ack */
3630
#ifdef CONFIG_TDLS
3631
if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3632
(psta->htpriv.ht_option == _TRUE) &&
3633
(psta->htpriv.ampdu_enable == _TRUE))
3634
RTW_INFO("Recv [%s] from direc link\n", __FUNCTION__);
3635
else
3636
#endif /* CONFIG_TDLS */
3637
if (!pmlmeinfo->HT_enable)
3638
return _SUCCESS;
3639
3640
action = frame_body[1];
3641
RTW_INFO("%s, action=%d\n", __FUNCTION__, action);
3642
switch (action) {
3643
case RTW_WLAN_ACTION_ADDBA_REQ: /* ADDBA request */
3644
3645
_rtw_memcpy(&(pmlmeinfo->ADDBA_req), &(frame_body[2]), sizeof(struct ADDBA_request));
3646
/* process_addba_req(padapter, (u8*)&(pmlmeinfo->ADDBA_req), GetAddr3Ptr(pframe)); */
3647
process_addba_req(padapter, (u8 *)&(pmlmeinfo->ADDBA_req), addr);
3648
3649
break;
3650
3651
case RTW_WLAN_ACTION_ADDBA_RESP: /* ADDBA response */
3652
3653
/* status = frame_body[3] | (frame_body[4] << 8); */ /* endian issue */
3654
status = RTW_GET_LE16(&frame_body[3]);
3655
tid = ((frame_body[5] >> 2) & 0x7);
3656
if (status == 0) {
3657
/* successful */
3658
RTW_INFO("agg_enable for TID=%d\n", tid);
3659
psta->htpriv.agg_enable_bitmap |= 1 << tid;
3660
psta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
3661
/* amsdu in ampdu */
3662
if (pregpriv->tx_ampdu_amsdu == 0)
3663
psta->htpriv.tx_amsdu_enable = _FALSE;
3664
else if (pregpriv->tx_ampdu_amsdu == 1)
3665
psta->htpriv.tx_amsdu_enable = _TRUE;
3666
else {
3667
if (frame_body[5] & 1)
3668
psta->htpriv.tx_amsdu_enable = _TRUE;
3669
}
3670
} else
3671
psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3672
3673
if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
3674
RTW_INFO("%s alive check - rx ADDBA response\n", __func__);
3675
psta->htpriv.agg_enable_bitmap &= ~BIT(tid);
3676
psta->expire_to = pstapriv->expire_to;
3677
psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
3678
}
3679
3680
/* RTW_INFO("marc: ADDBA RSP: %x\n", pmlmeinfo->agg_enable_bitmap); */
3681
break;
3682
3683
case RTW_WLAN_ACTION_DELBA: /* DELBA */
3684
if ((frame_body[3] & BIT(3)) == 0) {
3685
psta->htpriv.agg_enable_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3686
psta->htpriv.candidate_tid_bitmap &= ~(1 << ((frame_body[3] >> 4) & 0xf));
3687
3688
/* reason_code = frame_body[4] | (frame_body[5] << 8); */
3689
reason_code = RTW_GET_LE16(&frame_body[4]);
3690
} else if ((frame_body[3] & BIT(3)) == BIT(3)) {
3691
tid = (frame_body[3] >> 4) & 0x0F;
3692
3693
preorder_ctrl = &psta->recvreorder_ctrl[tid];
3694
preorder_ctrl->enable = _FALSE;
3695
preorder_ctrl->ampdu_size = RX_AMPDU_SIZE_INVALID;
3696
}
3697
3698
RTW_INFO("%s(): DELBA: %x(%x)\n", __FUNCTION__, pmlmeinfo->agg_enable_bitmap, reason_code);
3699
/* todo: how to notify the host while receiving DELETE BA */
3700
break;
3701
3702
default:
3703
break;
3704
}
3705
}
3706
#endif /* CONFIG_80211N_HT */
3707
return _SUCCESS;
3708
}
3709
3710
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
3711
u32 rtw_build_vendor_ie(_adapter *padapter , unsigned char **pframe , u8 mgmt_frame_tyte)
3712
{
3713
int vendor_ie_num = 0;
3714
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
3715
u32 len = 0;
3716
3717
for (vendor_ie_num = 0 ; vendor_ie_num < WLAN_MAX_VENDOR_IE_NUM ; vendor_ie_num++) {
3718
if (pmlmepriv->vendor_ielen[vendor_ie_num] > 0 && pmlmepriv->vendor_ie_mask[vendor_ie_num] & mgmt_frame_tyte) {
3719
_rtw_memcpy(*pframe , pmlmepriv->vendor_ie[vendor_ie_num] , pmlmepriv->vendor_ielen[vendor_ie_num]);
3720
*pframe += pmlmepriv->vendor_ielen[vendor_ie_num];
3721
len += pmlmepriv->vendor_ielen[vendor_ie_num];
3722
}
3723
}
3724
3725
return len;
3726
}
3727
#endif
3728
3729
#ifdef CONFIG_P2P
3730
int get_reg_classes_full_count(struct p2p_channels *channel_list)
3731
{
3732
int cnt = 0;
3733
int i;
3734
3735
for (i = 0; i < channel_list->reg_classes; i++)
3736
cnt += channel_list->reg_class[i].channels;
3737
3738
return cnt;
3739
}
3740
3741
void issue_p2p_GO_request(_adapter *padapter, u8 *raddr)
3742
{
3743
struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
3744
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
3745
u8 action = P2P_PUB_ACTION_ACTION;
3746
u32 p2poui = cpu_to_be32(P2POUI);
3747
u8 oui_subtype = P2P_GO_NEGO_REQ;
3748
u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
3749
u8 wpsielen = 0, p2pielen = 0;
3750
u16 len_channellist_attr = 0;
3751
#ifdef CONFIG_WFD
3752
u32 wfdielen = 0;
3753
#endif
3754
3755
struct xmit_frame *pmgntframe;
3756
struct pkt_attrib *pattrib;
3757
unsigned char *pframe;
3758
struct rtw_ieee80211_hdr *pwlanhdr;
3759
unsigned short *fctrl;
3760
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
3761
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
3762
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
3763
3764
3765
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
3766
if (pmgntframe == NULL)
3767
return;
3768
3769
RTW_INFO("[%s] In\n", __FUNCTION__);
3770
/* update attribute */
3771
pattrib = &pmgntframe->attrib;
3772
update_mgntframe_attrib(padapter, pattrib);
3773
3774
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
3775
3776
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
3777
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
3778
3779
fctrl = &(pwlanhdr->frame_ctl);
3780
*(fctrl) = 0;
3781
3782
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
3783
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
3784
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
3785
3786
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
3787
pmlmeext->mgnt_seq++;
3788
set_frame_sub_type(pframe, WIFI_ACTION);
3789
3790
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
3791
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
3792
3793
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
3794
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
3795
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
3796
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
3797
pwdinfo->negotiation_dialog_token = 1; /* Initialize the dialog value */
3798
pframe = rtw_set_fixed_ie(pframe, 1, &pwdinfo->negotiation_dialog_token, &(pattrib->pktlen));
3799
3800
3801
3802
/* WPS Section */
3803
wpsielen = 0;
3804
/* WPS OUI */
3805
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
3806
wpsielen += 4;
3807
3808
/* WPS version */
3809
/* Type: */
3810
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
3811
wpsielen += 2;
3812
3813
/* Length: */
3814
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
3815
wpsielen += 2;
3816
3817
/* Value: */
3818
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
3819
3820
/* Device Password ID */
3821
/* Type: */
3822
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
3823
wpsielen += 2;
3824
3825
/* Length: */
3826
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
3827
wpsielen += 2;
3828
3829
/* Value: */
3830
3831
if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN)
3832
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
3833
else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN)
3834
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
3835
else if (pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PBC)
3836
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
3837
3838
wpsielen += 2;
3839
3840
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
3841
3842
3843
/* P2P IE Section. */
3844
3845
/* P2P OUI */
3846
p2pielen = 0;
3847
p2pie[p2pielen++] = 0x50;
3848
p2pie[p2pielen++] = 0x6F;
3849
p2pie[p2pielen++] = 0x9A;
3850
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
3851
3852
/* Commented by Albert 20110306 */
3853
/* According to the P2P Specification, the group negoitation request frame should contain 9 P2P attributes */
3854
/* 1. P2P Capability */
3855
/* 2. Group Owner Intent */
3856
/* 3. Configuration Timeout */
3857
/* 4. Listen Channel */
3858
/* 5. Extended Listen Timing */
3859
/* 6. Intended P2P Interface Address */
3860
/* 7. Channel List */
3861
/* 8. P2P Device Info */
3862
/* 9. Operating Channel */
3863
3864
3865
/* P2P Capability */
3866
/* Type: */
3867
p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
3868
3869
/* Length: */
3870
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
3871
p2pielen += 2;
3872
3873
/* Value: */
3874
/* Device Capability Bitmap, 1 byte */
3875
p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
3876
3877
/* Group Capability Bitmap, 1 byte */
3878
if (pwdinfo->persistent_supported)
3879
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
3880
else
3881
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
3882
3883
3884
/* Group Owner Intent */
3885
/* Type: */
3886
p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
3887
3888
/* Length: */
3889
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
3890
p2pielen += 2;
3891
3892
/* Value: */
3893
/* Todo the tie breaker bit. */
3894
p2pie[p2pielen++] = ((pwdinfo->intent << 1) & 0xFE);
3895
3896
/* Configuration Timeout */
3897
/* Type: */
3898
p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
3899
3900
/* Length: */
3901
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
3902
p2pielen += 2;
3903
3904
/* Value: */
3905
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
3906
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
3907
3908
3909
/* Listen Channel */
3910
/* Type: */
3911
p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
3912
3913
/* Length: */
3914
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
3915
p2pielen += 2;
3916
3917
/* Value: */
3918
/* Country String */
3919
p2pie[p2pielen++] = 'X';
3920
p2pie[p2pielen++] = 'X';
3921
3922
/* The third byte should be set to 0x04. */
3923
/* Described in the "Operating Channel Attribute" section. */
3924
p2pie[p2pielen++] = 0x04;
3925
3926
/* Operating Class */
3927
p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
3928
3929
/* Channel Number */
3930
p2pie[p2pielen++] = pwdinfo->listen_channel; /* listening channel number */
3931
3932
3933
/* Extended Listen Timing ATTR */
3934
/* Type: */
3935
p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
3936
3937
/* Length: */
3938
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
3939
p2pielen += 2;
3940
3941
/* Value: */
3942
/* Availability Period */
3943
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
3944
p2pielen += 2;
3945
3946
/* Availability Interval */
3947
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
3948
p2pielen += 2;
3949
3950
3951
/* Intended P2P Interface Address */
3952
/* Type: */
3953
p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
3954
3955
/* Length: */
3956
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
3957
p2pielen += 2;
3958
3959
/* Value: */
3960
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
3961
p2pielen += ETH_ALEN;
3962
3963
3964
/* Channel List */
3965
/* Type: */
3966
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
3967
3968
/* Length: */
3969
/* Country String(3) */
3970
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
3971
/* + number of channels in all classes */
3972
len_channellist_attr = 3
3973
+ (1 + 1) * (u16)(ch_list->reg_classes)
3974
+ get_reg_classes_full_count(ch_list);
3975
3976
#ifdef CONFIG_CONCURRENT_MODE
3977
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
3978
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
3979
else
3980
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
3981
#else
3982
3983
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
3984
3985
#endif
3986
p2pielen += 2;
3987
3988
/* Value: */
3989
/* Country String */
3990
p2pie[p2pielen++] = 'X';
3991
p2pie[p2pielen++] = 'X';
3992
3993
/* The third byte should be set to 0x04. */
3994
/* Described in the "Operating Channel Attribute" section. */
3995
p2pie[p2pielen++] = 0x04;
3996
3997
/* Channel Entry List */
3998
3999
#ifdef CONFIG_CONCURRENT_MODE
4000
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4001
u8 union_ch = rtw_mi_get_union_chan(padapter);
4002
4003
/* Operating Class */
4004
if (union_ch > 14) {
4005
if (union_ch >= 149)
4006
p2pie[p2pielen++] = 0x7c;
4007
else
4008
p2pie[p2pielen++] = 0x73;
4009
} else
4010
p2pie[p2pielen++] = 0x51;
4011
4012
4013
/* Number of Channels */
4014
/* Just support 1 channel and this channel is AP's channel */
4015
p2pie[p2pielen++] = 1;
4016
4017
/* Channel List */
4018
p2pie[p2pielen++] = union_ch;
4019
} else
4020
#endif /* CONFIG_CONCURRENT_MODE */
4021
{
4022
int i, j;
4023
for (j = 0; j < ch_list->reg_classes; j++) {
4024
/* Operating Class */
4025
p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
4026
4027
/* Number of Channels */
4028
p2pie[p2pielen++] = ch_list->reg_class[j].channels;
4029
4030
/* Channel List */
4031
for (i = 0; i < ch_list->reg_class[j].channels; i++)
4032
p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
4033
}
4034
}
4035
4036
/* Device Info */
4037
/* Type: */
4038
p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4039
4040
/* Length: */
4041
/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
4042
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4043
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4044
p2pielen += 2;
4045
4046
/* Value: */
4047
/* P2P Device Address */
4048
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4049
p2pielen += ETH_ALEN;
4050
4051
/* Config Method */
4052
/* This field should be big endian. Noted by P2P specification. */
4053
4054
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4055
4056
p2pielen += 2;
4057
4058
/* Primary Device Type */
4059
/* Category ID */
4060
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4061
p2pielen += 2;
4062
4063
/* OUI */
4064
*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4065
p2pielen += 4;
4066
4067
/* Sub Category ID */
4068
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4069
p2pielen += 2;
4070
4071
/* Number of Secondary Device Types */
4072
p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
4073
4074
/* Device Name */
4075
/* Type: */
4076
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4077
p2pielen += 2;
4078
4079
/* Length: */
4080
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4081
p2pielen += 2;
4082
4083
/* Value: */
4084
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4085
p2pielen += pwdinfo->device_name_len;
4086
4087
4088
/* Operating Channel */
4089
/* Type: */
4090
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4091
4092
/* Length: */
4093
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4094
p2pielen += 2;
4095
4096
/* Value: */
4097
/* Country String */
4098
p2pie[p2pielen++] = 'X';
4099
p2pie[p2pielen++] = 'X';
4100
4101
/* The third byte should be set to 0x04. */
4102
/* Described in the "Operating Channel Attribute" section. */
4103
p2pie[p2pielen++] = 0x04;
4104
4105
/* Operating Class */
4106
if (pwdinfo->operating_channel <= 14) {
4107
/* Operating Class */
4108
p2pie[p2pielen++] = 0x51;
4109
} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4110
/* Operating Class */
4111
p2pie[p2pielen++] = 0x73;
4112
} else {
4113
/* Operating Class */
4114
p2pie[p2pielen++] = 0x7c;
4115
}
4116
4117
/* Channel Number */
4118
p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
4119
4120
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4121
4122
#ifdef CONFIG_WFD
4123
wfdielen = build_nego_req_wfd_ie(pwdinfo, pframe);
4124
pframe += wfdielen;
4125
pattrib->pktlen += wfdielen;
4126
#endif
4127
4128
pattrib->last_txcmdsz = pattrib->pktlen;
4129
4130
dump_mgntframe(padapter, pmgntframe);
4131
4132
return;
4133
4134
}
4135
4136
4137
void issue_p2p_GO_response(_adapter *padapter, u8 *raddr, u8 *frame_body, uint len, u8 result)
4138
{
4139
struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
4140
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4141
u8 action = P2P_PUB_ACTION_ACTION;
4142
u32 p2poui = cpu_to_be32(P2POUI);
4143
u8 oui_subtype = P2P_GO_NEGO_RESP;
4144
u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
4145
u8 p2pielen = 0;
4146
uint wpsielen = 0;
4147
u16 wps_devicepassword_id = 0x0000;
4148
uint wps_devicepassword_id_len = 0;
4149
u16 len_channellist_attr = 0;
4150
4151
struct xmit_frame *pmgntframe;
4152
struct pkt_attrib *pattrib;
4153
unsigned char *pframe;
4154
struct rtw_ieee80211_hdr *pwlanhdr;
4155
unsigned short *fctrl;
4156
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4157
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4158
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4159
4160
#ifdef CONFIG_WFD
4161
u32 wfdielen = 0;
4162
#endif
4163
4164
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4165
if (pmgntframe == NULL)
4166
return;
4167
4168
RTW_INFO("[%s] In, result = %d\n", __FUNCTION__, result);
4169
/* update attribute */
4170
pattrib = &pmgntframe->attrib;
4171
update_mgntframe_attrib(padapter, pattrib);
4172
4173
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4174
4175
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4176
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4177
4178
fctrl = &(pwlanhdr->frame_ctl);
4179
*(fctrl) = 0;
4180
4181
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4182
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4183
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4184
4185
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4186
pmlmeext->mgnt_seq++;
4187
set_frame_sub_type(pframe, WIFI_ACTION);
4188
4189
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4190
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4191
4192
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4193
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4194
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4195
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4196
pwdinfo->negotiation_dialog_token = frame_body[7]; /* The Dialog Token of provisioning discovery request frame. */
4197
pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4198
4199
/* Commented by Albert 20110328 */
4200
/* Try to get the device password ID from the WPS IE of group negotiation request frame */
4201
/* WiFi Direct test plan 5.1.15 */
4202
rtw_get_wps_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, wpsie, &wpsielen);
4203
rtw_get_wps_attr_content(wpsie, wpsielen, WPS_ATTR_DEVICE_PWID, (u8 *) &wps_devicepassword_id, &wps_devicepassword_id_len);
4204
wps_devicepassword_id = be16_to_cpu(wps_devicepassword_id);
4205
4206
_rtw_memset(wpsie, 0x00, 255);
4207
wpsielen = 0;
4208
4209
/* WPS Section */
4210
wpsielen = 0;
4211
/* WPS OUI */
4212
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
4213
wpsielen += 4;
4214
4215
/* WPS version */
4216
/* Type: */
4217
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
4218
wpsielen += 2;
4219
4220
/* Length: */
4221
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
4222
wpsielen += 2;
4223
4224
/* Value: */
4225
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
4226
4227
/* Device Password ID */
4228
/* Type: */
4229
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
4230
wpsielen += 2;
4231
4232
/* Length: */
4233
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
4234
wpsielen += 2;
4235
4236
/* Value: */
4237
if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
4238
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC);
4239
else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4240
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_USER_SPEC);
4241
else
4242
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_PBC);
4243
wpsielen += 2;
4244
4245
/* Commented by Kurt 20120113 */
4246
/* If some device wants to do p2p handshake without sending prov_disc_req */
4247
/* We have to get peer_req_cm from here. */
4248
if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "000", 3)) {
4249
if (wps_devicepassword_id == WPS_DPID_USER_SPEC)
4250
_rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "dis", 3);
4251
else if (wps_devicepassword_id == WPS_DPID_REGISTRAR_SPEC)
4252
_rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pad", 3);
4253
else
4254
_rtw_memcpy(pwdinfo->rx_prov_disc_info.strconfig_method_desc_of_prov_disc_req, "pbc", 3);
4255
}
4256
4257
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
4258
4259
4260
/* P2P IE Section. */
4261
4262
/* P2P OUI */
4263
p2pielen = 0;
4264
p2pie[p2pielen++] = 0x50;
4265
p2pie[p2pielen++] = 0x6F;
4266
p2pie[p2pielen++] = 0x9A;
4267
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4268
4269
/* Commented by Albert 20100908 */
4270
/* According to the P2P Specification, the group negoitation response frame should contain 9 P2P attributes */
4271
/* 1. Status */
4272
/* 2. P2P Capability */
4273
/* 3. Group Owner Intent */
4274
/* 4. Configuration Timeout */
4275
/* 5. Operating Channel */
4276
/* 6. Intended P2P Interface Address */
4277
/* 7. Channel List */
4278
/* 8. Device Info */
4279
/* 9. Group ID ( Only GO ) */
4280
4281
4282
/* ToDo: */
4283
4284
/* P2P Status */
4285
/* Type: */
4286
p2pie[p2pielen++] = P2P_ATTR_STATUS;
4287
4288
/* Length: */
4289
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4290
p2pielen += 2;
4291
4292
/* Value: */
4293
p2pie[p2pielen++] = result;
4294
4295
/* P2P Capability */
4296
/* Type: */
4297
p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4298
4299
/* Length: */
4300
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4301
p2pielen += 2;
4302
4303
/* Value: */
4304
/* Device Capability Bitmap, 1 byte */
4305
4306
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4307
/* Commented by Albert 2011/03/08 */
4308
/* According to the P2P specification */
4309
/* if the sending device will be client, the P2P Capability should be reserved of group negotation response frame */
4310
p2pie[p2pielen++] = 0;
4311
} else {
4312
/* Be group owner or meet the error case */
4313
p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4314
}
4315
4316
/* Group Capability Bitmap, 1 byte */
4317
if (pwdinfo->persistent_supported)
4318
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4319
else
4320
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4321
4322
/* Group Owner Intent */
4323
/* Type: */
4324
p2pie[p2pielen++] = P2P_ATTR_GO_INTENT;
4325
4326
/* Length: */
4327
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4328
p2pielen += 2;
4329
4330
/* Value: */
4331
if (pwdinfo->peer_intent & 0x01) {
4332
/* Peer's tie breaker bit is 1, our tie breaker bit should be 0 */
4333
p2pie[p2pielen++] = (pwdinfo->intent << 1);
4334
} else {
4335
/* Peer's tie breaker bit is 0, our tie breaker bit should be 1 */
4336
p2pie[p2pielen++] = ((pwdinfo->intent << 1) | BIT(0));
4337
}
4338
4339
4340
/* Configuration Timeout */
4341
/* Type: */
4342
p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4343
4344
/* Length: */
4345
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4346
p2pielen += 2;
4347
4348
/* Value: */
4349
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
4350
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
4351
4352
/* Operating Channel */
4353
/* Type: */
4354
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4355
4356
/* Length: */
4357
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4358
p2pielen += 2;
4359
4360
/* Value: */
4361
/* Country String */
4362
p2pie[p2pielen++] = 'X';
4363
p2pie[p2pielen++] = 'X';
4364
4365
/* The third byte should be set to 0x04. */
4366
/* Described in the "Operating Channel Attribute" section. */
4367
p2pie[p2pielen++] = 0x04;
4368
4369
/* Operating Class */
4370
if (pwdinfo->operating_channel <= 14) {
4371
/* Operating Class */
4372
p2pie[p2pielen++] = 0x51;
4373
} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4374
/* Operating Class */
4375
p2pie[p2pielen++] = 0x73;
4376
} else {
4377
/* Operating Class */
4378
p2pie[p2pielen++] = 0x7c;
4379
}
4380
4381
/* Channel Number */
4382
p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
4383
4384
/* Intended P2P Interface Address */
4385
/* Type: */
4386
p2pie[p2pielen++] = P2P_ATTR_INTENDED_IF_ADDR;
4387
4388
/* Length: */
4389
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4390
p2pielen += 2;
4391
4392
/* Value: */
4393
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4394
p2pielen += ETH_ALEN;
4395
4396
/* Channel List */
4397
/* Type: */
4398
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4399
4400
/* Country String(3) */
4401
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4402
/* + number of channels in all classes */
4403
len_channellist_attr = 3
4404
+ (1 + 1) * (u16)ch_list->reg_classes
4405
+ get_reg_classes_full_count(ch_list);
4406
4407
#ifdef CONFIG_CONCURRENT_MODE
4408
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4409
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4410
else
4411
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4412
#else
4413
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4414
4415
#endif
4416
p2pielen += 2;
4417
4418
/* Value: */
4419
/* Country String */
4420
p2pie[p2pielen++] = 'X';
4421
p2pie[p2pielen++] = 'X';
4422
4423
/* The third byte should be set to 0x04. */
4424
/* Described in the "Operating Channel Attribute" section. */
4425
p2pie[p2pielen++] = 0x04;
4426
4427
/* Channel Entry List */
4428
4429
#ifdef CONFIG_CONCURRENT_MODE
4430
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4431
4432
u8 union_chan = rtw_mi_get_union_chan(padapter);
4433
4434
/*Operating Class*/
4435
if (union_chan > 14) {
4436
if (union_chan >= 149)
4437
p2pie[p2pielen++] = 0x7c;
4438
else
4439
p2pie[p2pielen++] = 0x73;
4440
4441
} else
4442
p2pie[p2pielen++] = 0x51;
4443
4444
/* Number of Channels
4445
Just support 1 channel and this channel is AP's channel*/
4446
p2pie[p2pielen++] = 1;
4447
4448
/*Channel List*/
4449
p2pie[p2pielen++] = union_chan;
4450
} else
4451
#endif /* CONFIG_CONCURRENT_MODE */
4452
{
4453
int i, j;
4454
for (j = 0; j < ch_list->reg_classes; j++) {
4455
/* Operating Class */
4456
p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
4457
4458
/* Number of Channels */
4459
p2pie[p2pielen++] = ch_list->reg_class[j].channels;
4460
4461
/* Channel List */
4462
for (i = 0; i < ch_list->reg_class[j].channels; i++)
4463
p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
4464
}
4465
}
4466
4467
/* Device Info */
4468
/* Type: */
4469
p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
4470
4471
/* Length: */
4472
/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
4473
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
4474
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
4475
p2pielen += 2;
4476
4477
/* Value: */
4478
/* P2P Device Address */
4479
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
4480
p2pielen += ETH_ALEN;
4481
4482
/* Config Method */
4483
/* This field should be big endian. Noted by P2P specification. */
4484
4485
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
4486
4487
p2pielen += 2;
4488
4489
/* Primary Device Type */
4490
/* Category ID */
4491
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
4492
p2pielen += 2;
4493
4494
/* OUI */
4495
*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
4496
p2pielen += 4;
4497
4498
/* Sub Category ID */
4499
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
4500
p2pielen += 2;
4501
4502
/* Number of Secondary Device Types */
4503
p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
4504
4505
/* Device Name */
4506
/* Type: */
4507
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
4508
p2pielen += 2;
4509
4510
/* Length: */
4511
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
4512
p2pielen += 2;
4513
4514
/* Value: */
4515
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name , pwdinfo->device_name_len);
4516
p2pielen += pwdinfo->device_name_len;
4517
4518
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4519
/* Group ID Attribute */
4520
/* Type: */
4521
p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
4522
4523
/* Length: */
4524
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
4525
p2pielen += 2;
4526
4527
/* Value: */
4528
/* p2P Device Address */
4529
_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
4530
p2pielen += ETH_ALEN;
4531
4532
/* SSID */
4533
_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
4534
p2pielen += pwdinfo->nego_ssidlen;
4535
4536
}
4537
4538
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4539
4540
#ifdef CONFIG_WFD
4541
wfdielen = build_nego_resp_wfd_ie(pwdinfo, pframe);
4542
pframe += wfdielen;
4543
pattrib->pktlen += wfdielen;
4544
#endif
4545
4546
pattrib->last_txcmdsz = pattrib->pktlen;
4547
4548
dump_mgntframe(padapter, pmgntframe);
4549
4550
return;
4551
4552
}
4553
4554
void issue_p2p_GO_confirm(_adapter *padapter, u8 *raddr, u8 result)
4555
{
4556
4557
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4558
u8 action = P2P_PUB_ACTION_ACTION;
4559
u32 p2poui = cpu_to_be32(P2POUI);
4560
u8 oui_subtype = P2P_GO_NEGO_CONF;
4561
u8 p2pie[255] = { 0x00 };
4562
u8 p2pielen = 0;
4563
4564
struct xmit_frame *pmgntframe;
4565
struct pkt_attrib *pattrib;
4566
unsigned char *pframe;
4567
struct rtw_ieee80211_hdr *pwlanhdr;
4568
unsigned short *fctrl;
4569
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4570
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4571
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4572
#ifdef CONFIG_WFD
4573
u32 wfdielen = 0;
4574
#endif
4575
4576
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4577
if (pmgntframe == NULL)
4578
return;
4579
4580
RTW_INFO("[%s] In\n", __FUNCTION__);
4581
/* update attribute */
4582
pattrib = &pmgntframe->attrib;
4583
update_mgntframe_attrib(padapter, pattrib);
4584
4585
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4586
4587
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4588
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4589
4590
fctrl = &(pwlanhdr->frame_ctl);
4591
*(fctrl) = 0;
4592
4593
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4594
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4595
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
4596
4597
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4598
pmlmeext->mgnt_seq++;
4599
set_frame_sub_type(pframe, WIFI_ACTION);
4600
4601
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4602
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4603
4604
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4605
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4606
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4607
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4608
pframe = rtw_set_fixed_ie(pframe, 1, &(pwdinfo->negotiation_dialog_token), &(pattrib->pktlen));
4609
4610
4611
4612
/* P2P IE Section. */
4613
4614
/* P2P OUI */
4615
p2pielen = 0;
4616
p2pie[p2pielen++] = 0x50;
4617
p2pie[p2pielen++] = 0x6F;
4618
p2pie[p2pielen++] = 0x9A;
4619
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4620
4621
/* Commented by Albert 20110306 */
4622
/* According to the P2P Specification, the group negoitation request frame should contain 5 P2P attributes */
4623
/* 1. Status */
4624
/* 2. P2P Capability */
4625
/* 3. Operating Channel */
4626
/* 4. Channel List */
4627
/* 5. Group ID ( if this WiFi is GO ) */
4628
4629
/* P2P Status */
4630
/* Type: */
4631
p2pie[p2pielen++] = P2P_ATTR_STATUS;
4632
4633
/* Length: */
4634
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4635
p2pielen += 2;
4636
4637
/* Value: */
4638
p2pie[p2pielen++] = result;
4639
4640
/* P2P Capability */
4641
/* Type: */
4642
p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
4643
4644
/* Length: */
4645
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4646
p2pielen += 2;
4647
4648
/* Value: */
4649
/* Device Capability Bitmap, 1 byte */
4650
p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
4651
4652
/* Group Capability Bitmap, 1 byte */
4653
if (pwdinfo->persistent_supported)
4654
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN | P2P_GRPCAP_PERSISTENT_GROUP;
4655
else
4656
p2pie[p2pielen++] = P2P_GRPCAP_CROSS_CONN;
4657
4658
4659
/* Operating Channel */
4660
/* Type: */
4661
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4662
4663
/* Length: */
4664
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4665
p2pielen += 2;
4666
4667
/* Value: */
4668
/* Country String */
4669
p2pie[p2pielen++] = 'X';
4670
p2pie[p2pielen++] = 'X';
4671
4672
/* The third byte should be set to 0x04. */
4673
/* Described in the "Operating Channel Attribute" section. */
4674
p2pie[p2pielen++] = 0x04;
4675
4676
4677
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4678
if (pwdinfo->peer_operating_ch <= 14) {
4679
/* Operating Class */
4680
p2pie[p2pielen++] = 0x51;
4681
} else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
4682
/* Operating Class */
4683
p2pie[p2pielen++] = 0x73;
4684
} else {
4685
/* Operating Class */
4686
p2pie[p2pielen++] = 0x7c;
4687
}
4688
4689
p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
4690
} else {
4691
if (pwdinfo->operating_channel <= 14) {
4692
/* Operating Class */
4693
p2pie[p2pielen++] = 0x51;
4694
} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4695
/* Operating Class */
4696
p2pie[p2pielen++] = 0x73;
4697
} else {
4698
/* Operating Class */
4699
p2pie[p2pielen++] = 0x7c;
4700
}
4701
4702
/* Channel Number */
4703
p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
4704
}
4705
4706
4707
/* Channel List */
4708
/* Type: */
4709
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4710
4711
*(u16 *)(p2pie + p2pielen) = 6;
4712
p2pielen += 2;
4713
4714
/* Country String */
4715
p2pie[p2pielen++] = 'X';
4716
p2pie[p2pielen++] = 'X';
4717
4718
/* The third byte should be set to 0x04. */
4719
/* Described in the "Operating Channel Attribute" section. */
4720
p2pie[p2pielen++] = 0x04;
4721
4722
/* Value: */
4723
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_CLIENT)) {
4724
if (pwdinfo->peer_operating_ch <= 14) {
4725
/* Operating Class */
4726
p2pie[p2pielen++] = 0x51;
4727
} else if ((pwdinfo->peer_operating_ch >= 36) && (pwdinfo->peer_operating_ch <= 48)) {
4728
/* Operating Class */
4729
p2pie[p2pielen++] = 0x73;
4730
} else {
4731
/* Operating Class */
4732
p2pie[p2pielen++] = 0x7c;
4733
}
4734
p2pie[p2pielen++] = 1;
4735
p2pie[p2pielen++] = pwdinfo->peer_operating_ch;
4736
} else {
4737
if (pwdinfo->operating_channel <= 14) {
4738
/* Operating Class */
4739
p2pie[p2pielen++] = 0x51;
4740
} else if ((pwdinfo->operating_channel >= 36) && (pwdinfo->operating_channel <= 48)) {
4741
/* Operating Class */
4742
p2pie[p2pielen++] = 0x73;
4743
} else {
4744
/* Operating Class */
4745
p2pie[p2pielen++] = 0x7c;
4746
}
4747
4748
/* Channel Number */
4749
p2pie[p2pielen++] = 1;
4750
p2pie[p2pielen++] = pwdinfo->operating_channel; /* Use the listen channel as the operating channel */
4751
}
4752
4753
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
4754
/* Group ID Attribute */
4755
/* Type: */
4756
p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
4757
4758
/* Length: */
4759
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN + pwdinfo->nego_ssidlen);
4760
p2pielen += 2;
4761
4762
/* Value: */
4763
/* p2P Device Address */
4764
_rtw_memcpy(p2pie + p2pielen , pwdinfo->device_addr, ETH_ALEN);
4765
p2pielen += ETH_ALEN;
4766
4767
/* SSID */
4768
_rtw_memcpy(p2pie + p2pielen, pwdinfo->nego_ssid, pwdinfo->nego_ssidlen);
4769
p2pielen += pwdinfo->nego_ssidlen;
4770
}
4771
4772
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
4773
4774
#ifdef CONFIG_WFD
4775
wfdielen = build_nego_confirm_wfd_ie(pwdinfo, pframe);
4776
pframe += wfdielen;
4777
pattrib->pktlen += wfdielen;
4778
#endif
4779
4780
pattrib->last_txcmdsz = pattrib->pktlen;
4781
4782
dump_mgntframe(padapter, pmgntframe);
4783
4784
return;
4785
4786
}
4787
4788
void issue_p2p_invitation_request(_adapter *padapter, u8 *raddr)
4789
{
4790
struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
4791
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
4792
u8 action = P2P_PUB_ACTION_ACTION;
4793
u32 p2poui = cpu_to_be32(P2POUI);
4794
u8 oui_subtype = P2P_INVIT_REQ;
4795
u8 p2pie[255] = { 0x00 };
4796
u8 p2pielen = 0;
4797
u8 dialogToken = 3;
4798
u16 len_channellist_attr = 0;
4799
#ifdef CONFIG_WFD
4800
u32 wfdielen = 0;
4801
#endif
4802
4803
struct xmit_frame *pmgntframe;
4804
struct pkt_attrib *pattrib;
4805
unsigned char *pframe;
4806
struct rtw_ieee80211_hdr *pwlanhdr;
4807
unsigned short *fctrl;
4808
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
4809
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
4810
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
4811
4812
4813
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
4814
if (pmgntframe == NULL)
4815
return;
4816
4817
/* update attribute */
4818
pattrib = &pmgntframe->attrib;
4819
update_mgntframe_attrib(padapter, pattrib);
4820
4821
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
4822
4823
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
4824
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
4825
4826
fctrl = &(pwlanhdr->frame_ctl);
4827
*(fctrl) = 0;
4828
4829
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
4830
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
4831
_rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
4832
4833
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
4834
pmlmeext->mgnt_seq++;
4835
set_frame_sub_type(pframe, WIFI_ACTION);
4836
4837
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
4838
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
4839
4840
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
4841
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
4842
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
4843
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
4844
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
4845
4846
/* P2P IE Section. */
4847
4848
/* P2P OUI */
4849
p2pielen = 0;
4850
p2pie[p2pielen++] = 0x50;
4851
p2pie[p2pielen++] = 0x6F;
4852
p2pie[p2pielen++] = 0x9A;
4853
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
4854
4855
/* Commented by Albert 20101011 */
4856
/* According to the P2P Specification, the P2P Invitation request frame should contain 7 P2P attributes */
4857
/* 1. Configuration Timeout */
4858
/* 2. Invitation Flags */
4859
/* 3. Operating Channel ( Only GO ) */
4860
/* 4. P2P Group BSSID ( Should be included if I am the GO ) */
4861
/* 5. Channel List */
4862
/* 6. P2P Group ID */
4863
/* 7. P2P Device Info */
4864
4865
/* Configuration Timeout */
4866
/* Type: */
4867
p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
4868
4869
/* Length: */
4870
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
4871
p2pielen += 2;
4872
4873
/* Value: */
4874
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
4875
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
4876
4877
/* Invitation Flags */
4878
/* Type: */
4879
p2pie[p2pielen++] = P2P_ATTR_INVITATION_FLAGS;
4880
4881
/* Length: */
4882
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
4883
p2pielen += 2;
4884
4885
/* Value: */
4886
p2pie[p2pielen++] = P2P_INVITATION_FLAGS_PERSISTENT;
4887
4888
4889
/* Operating Channel */
4890
/* Type: */
4891
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
4892
4893
/* Length: */
4894
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
4895
p2pielen += 2;
4896
4897
/* Value: */
4898
/* Country String */
4899
p2pie[p2pielen++] = 'X';
4900
p2pie[p2pielen++] = 'X';
4901
4902
/* The third byte should be set to 0x04. */
4903
/* Described in the "Operating Channel Attribute" section. */
4904
p2pie[p2pielen++] = 0x04;
4905
4906
/* Operating Class */
4907
if (pwdinfo->invitereq_info.operating_ch <= 14)
4908
p2pie[p2pielen++] = 0x51;
4909
else if ((pwdinfo->invitereq_info.operating_ch >= 36) && (pwdinfo->invitereq_info.operating_ch <= 48))
4910
p2pie[p2pielen++] = 0x73;
4911
else
4912
p2pie[p2pielen++] = 0x7c;
4913
4914
/* Channel Number */
4915
p2pie[p2pielen++] = pwdinfo->invitereq_info.operating_ch; /* operating channel number */
4916
4917
if (_rtw_memcmp(adapter_mac_addr(padapter), pwdinfo->invitereq_info.go_bssid, ETH_ALEN)) {
4918
/* P2P Group BSSID */
4919
/* Type: */
4920
p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
4921
4922
/* Length: */
4923
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
4924
p2pielen += 2;
4925
4926
/* Value: */
4927
/* P2P Device Address for GO */
4928
_rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
4929
p2pielen += ETH_ALEN;
4930
}
4931
4932
/* Channel List */
4933
/* Type: */
4934
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
4935
4936
4937
/* Length: */
4938
/* Country String(3) */
4939
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
4940
/* + number of channels in all classes */
4941
len_channellist_attr = 3
4942
+ (1 + 1) * (u16)ch_list->reg_classes
4943
+ get_reg_classes_full_count(ch_list);
4944
4945
#ifdef CONFIG_CONCURRENT_MODE
4946
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
4947
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
4948
else
4949
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4950
#else
4951
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
4952
#endif
4953
p2pielen += 2;
4954
4955
/* Value: */
4956
/* Country String */
4957
p2pie[p2pielen++] = 'X';
4958
p2pie[p2pielen++] = 'X';
4959
4960
/* The third byte should be set to 0x04. */
4961
/* Described in the "Operating Channel Attribute" section. */
4962
p2pie[p2pielen++] = 0x04;
4963
4964
/* Channel Entry List */
4965
#ifdef CONFIG_CONCURRENT_MODE
4966
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
4967
u8 union_ch = rtw_mi_get_union_chan(padapter);
4968
4969
/* Operating Class */
4970
if (union_ch > 14) {
4971
if (union_ch >= 149)
4972
p2pie[p2pielen++] = 0x7c;
4973
else
4974
p2pie[p2pielen++] = 0x73;
4975
} else
4976
p2pie[p2pielen++] = 0x51;
4977
4978
4979
/* Number of Channels */
4980
/* Just support 1 channel and this channel is AP's channel */
4981
p2pie[p2pielen++] = 1;
4982
4983
/* Channel List */
4984
p2pie[p2pielen++] = union_ch;
4985
} else
4986
#endif /* CONFIG_CONCURRENT_MODE */
4987
{
4988
int i, j;
4989
for (j = 0; j < ch_list->reg_classes; j++) {
4990
/* Operating Class */
4991
p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
4992
4993
/* Number of Channels */
4994
p2pie[p2pielen++] = ch_list->reg_class[j].channels;
4995
4996
/* Channel List */
4997
for (i = 0; i < ch_list->reg_class[j].channels; i++)
4998
p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
4999
}
5000
}
5001
5002
5003
/* P2P Group ID */
5004
/* Type: */
5005
p2pie[p2pielen++] = P2P_ATTR_GROUP_ID;
5006
5007
/* Length: */
5008
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(6 + pwdinfo->invitereq_info.ssidlen);
5009
p2pielen += 2;
5010
5011
/* Value: */
5012
/* P2P Device Address for GO */
5013
_rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_bssid, ETH_ALEN);
5014
p2pielen += ETH_ALEN;
5015
5016
/* SSID */
5017
_rtw_memcpy(p2pie + p2pielen, pwdinfo->invitereq_info.go_ssid, pwdinfo->invitereq_info.ssidlen);
5018
p2pielen += pwdinfo->invitereq_info.ssidlen;
5019
5020
5021
/* Device Info */
5022
/* Type: */
5023
p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
5024
5025
/* Length: */
5026
/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
5027
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
5028
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
5029
p2pielen += 2;
5030
5031
/* Value: */
5032
/* P2P Device Address */
5033
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5034
p2pielen += ETH_ALEN;
5035
5036
/* Config Method */
5037
/* This field should be big endian. Noted by P2P specification. */
5038
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
5039
p2pielen += 2;
5040
5041
/* Primary Device Type */
5042
/* Category ID */
5043
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5044
p2pielen += 2;
5045
5046
/* OUI */
5047
*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
5048
p2pielen += 4;
5049
5050
/* Sub Category ID */
5051
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5052
p2pielen += 2;
5053
5054
/* Number of Secondary Device Types */
5055
p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
5056
5057
/* Device Name */
5058
/* Type: */
5059
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5060
p2pielen += 2;
5061
5062
/* Length: */
5063
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
5064
p2pielen += 2;
5065
5066
/* Value: */
5067
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
5068
p2pielen += pwdinfo->device_name_len;
5069
5070
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5071
5072
#ifdef CONFIG_WFD
5073
wfdielen = build_invitation_req_wfd_ie(pwdinfo, pframe);
5074
pframe += wfdielen;
5075
pattrib->pktlen += wfdielen;
5076
#endif
5077
5078
pattrib->last_txcmdsz = pattrib->pktlen;
5079
5080
dump_mgntframe(padapter, pmgntframe);
5081
5082
return;
5083
5084
}
5085
5086
void issue_p2p_invitation_response(_adapter *padapter, u8 *raddr, u8 dialogToken, u8 status_code)
5087
{
5088
struct p2p_channels *ch_list = &(adapter_to_rfctl(padapter)->channel_list);
5089
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5090
u8 action = P2P_PUB_ACTION_ACTION;
5091
u32 p2poui = cpu_to_be32(P2POUI);
5092
u8 oui_subtype = P2P_INVIT_RESP;
5093
u8 p2pie[255] = { 0x00 };
5094
u8 p2pielen = 0;
5095
u16 len_channellist_attr = 0;
5096
#ifdef CONFIG_WFD
5097
u32 wfdielen = 0;
5098
#endif
5099
5100
struct xmit_frame *pmgntframe;
5101
struct pkt_attrib *pattrib;
5102
unsigned char *pframe;
5103
struct rtw_ieee80211_hdr *pwlanhdr;
5104
unsigned short *fctrl;
5105
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5106
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5107
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5108
5109
5110
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5111
if (pmgntframe == NULL)
5112
return;
5113
5114
/* update attribute */
5115
pattrib = &pmgntframe->attrib;
5116
update_mgntframe_attrib(padapter, pattrib);
5117
5118
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5119
5120
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5121
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5122
5123
fctrl = &(pwlanhdr->frame_ctl);
5124
*(fctrl) = 0;
5125
5126
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
5127
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5128
_rtw_memcpy(pwlanhdr->addr3, raddr, ETH_ALEN);
5129
5130
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5131
pmlmeext->mgnt_seq++;
5132
set_frame_sub_type(pframe, WIFI_ACTION);
5133
5134
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5135
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5136
5137
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5138
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5139
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5140
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5141
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5142
5143
/* P2P IE Section. */
5144
5145
/* P2P OUI */
5146
p2pielen = 0;
5147
p2pie[p2pielen++] = 0x50;
5148
p2pie[p2pielen++] = 0x6F;
5149
p2pie[p2pielen++] = 0x9A;
5150
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5151
5152
/* Commented by Albert 20101005 */
5153
/* According to the P2P Specification, the P2P Invitation response frame should contain 5 P2P attributes */
5154
/* 1. Status */
5155
/* 2. Configuration Timeout */
5156
/* 3. Operating Channel ( Only GO ) */
5157
/* 4. P2P Group BSSID ( Only GO ) */
5158
/* 5. Channel List */
5159
5160
/* P2P Status */
5161
/* Type: */
5162
p2pie[p2pielen++] = P2P_ATTR_STATUS;
5163
5164
/* Length: */
5165
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0001);
5166
p2pielen += 2;
5167
5168
/* Value: */
5169
/* When status code is P2P_STATUS_FAIL_INFO_UNAVAILABLE. */
5170
/* Sent the event receiving the P2P Invitation Req frame to DMP UI. */
5171
/* DMP had to compare the MAC address to find out the profile. */
5172
/* So, the WiFi driver will send the P2P_STATUS_FAIL_INFO_UNAVAILABLE to NB. */
5173
/* If the UI found the corresponding profile, the WiFi driver sends the P2P Invitation Req */
5174
/* to NB to rebuild the persistent group. */
5175
p2pie[p2pielen++] = status_code;
5176
5177
/* Configuration Timeout */
5178
/* Type: */
5179
p2pie[p2pielen++] = P2P_ATTR_CONF_TIMEOUT;
5180
5181
/* Length: */
5182
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5183
p2pielen += 2;
5184
5185
/* Value: */
5186
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P GO */
5187
p2pie[p2pielen++] = 200; /* 2 seconds needed to be the P2P Client */
5188
5189
if (status_code == P2P_STATUS_SUCCESS) {
5190
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
5191
/* The P2P Invitation request frame asks this Wi-Fi device to be the P2P GO */
5192
/* In this case, the P2P Invitation response frame should carry the two more P2P attributes. */
5193
/* First one is operating channel attribute. */
5194
/* Second one is P2P Group BSSID attribute. */
5195
5196
/* Operating Channel */
5197
/* Type: */
5198
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
5199
5200
/* Length: */
5201
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5202
p2pielen += 2;
5203
5204
/* Value: */
5205
/* Country String */
5206
p2pie[p2pielen++] = 'X';
5207
p2pie[p2pielen++] = 'X';
5208
5209
/* The third byte should be set to 0x04. */
5210
/* Described in the "Operating Channel Attribute" section. */
5211
p2pie[p2pielen++] = 0x04;
5212
5213
/* Operating Class */
5214
p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
5215
5216
/* Channel Number */
5217
p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
5218
5219
5220
/* P2P Group BSSID */
5221
/* Type: */
5222
p2pie[p2pielen++] = P2P_ATTR_GROUP_BSSID;
5223
5224
/* Length: */
5225
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(ETH_ALEN);
5226
p2pielen += 2;
5227
5228
/* Value: */
5229
/* P2P Device Address for GO */
5230
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
5231
p2pielen += ETH_ALEN;
5232
5233
}
5234
5235
/* Channel List */
5236
/* Type: */
5237
p2pie[p2pielen++] = P2P_ATTR_CH_LIST;
5238
5239
/* Length: */
5240
/* Country String(3) */
5241
/* + ( Operating Class (1) + Number of Channels(1) ) * Operation Classes (?) */
5242
/* + number of channels in all classes */
5243
len_channellist_attr = 3
5244
+ (1 + 1) * (u16)ch_list->reg_classes
5245
+ get_reg_classes_full_count(ch_list);
5246
5247
#ifdef CONFIG_CONCURRENT_MODE
5248
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0)
5249
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(5 + 1);
5250
else
5251
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5252
#else
5253
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(len_channellist_attr);
5254
#endif
5255
p2pielen += 2;
5256
5257
/* Value: */
5258
/* Country String */
5259
p2pie[p2pielen++] = 'X';
5260
p2pie[p2pielen++] = 'X';
5261
5262
/* The third byte should be set to 0x04. */
5263
/* Described in the "Operating Channel Attribute" section. */
5264
p2pie[p2pielen++] = 0x04;
5265
5266
/* Channel Entry List */
5267
#ifdef CONFIG_CONCURRENT_MODE
5268
if (rtw_mi_check_status(padapter, MI_LINKED) && padapter->registrypriv.full_ch_in_p2p_handshake == 0) {
5269
u8 union_ch = rtw_mi_get_union_chan(padapter);
5270
5271
/* Operating Class */
5272
if (union_ch > 14) {
5273
if (union_ch >= 149)
5274
p2pie[p2pielen++] = 0x7c;
5275
else
5276
p2pie[p2pielen++] = 0x73;
5277
} else
5278
p2pie[p2pielen++] = 0x51;
5279
5280
5281
/* Number of Channels */
5282
/* Just support 1 channel and this channel is AP's channel */
5283
p2pie[p2pielen++] = 1;
5284
5285
/* Channel List */
5286
p2pie[p2pielen++] = union_ch;
5287
} else
5288
#endif /* CONFIG_CONCURRENT_MODE */
5289
{
5290
int i, j;
5291
for (j = 0; j < ch_list->reg_classes; j++) {
5292
/* Operating Class */
5293
p2pie[p2pielen++] = ch_list->reg_class[j].reg_class;
5294
5295
/* Number of Channels */
5296
p2pie[p2pielen++] = ch_list->reg_class[j].channels;
5297
5298
/* Channel List */
5299
for (i = 0; i < ch_list->reg_class[j].channels; i++)
5300
p2pie[p2pielen++] = ch_list->reg_class[j].channel[i];
5301
}
5302
}
5303
}
5304
5305
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
5306
5307
#ifdef CONFIG_WFD
5308
wfdielen = build_invitation_resp_wfd_ie(pwdinfo, pframe);
5309
pframe += wfdielen;
5310
pattrib->pktlen += wfdielen;
5311
#endif
5312
5313
pattrib->last_txcmdsz = pattrib->pktlen;
5314
5315
dump_mgntframe(padapter, pmgntframe);
5316
5317
return;
5318
5319
}
5320
5321
void issue_p2p_provision_request(_adapter *padapter, u8 *pssid, u8 ussidlen, u8 *pdev_raddr)
5322
{
5323
unsigned char category = RTW_WLAN_CATEGORY_PUBLIC;
5324
u8 action = P2P_PUB_ACTION_ACTION;
5325
u8 dialogToken = 1;
5326
u32 p2poui = cpu_to_be32(P2POUI);
5327
u8 oui_subtype = P2P_PROVISION_DISC_REQ;
5328
u8 wpsie[100] = { 0x00 };
5329
u8 wpsielen = 0;
5330
u32 p2pielen = 0;
5331
#ifdef CONFIG_WFD
5332
u32 wfdielen = 0;
5333
#endif
5334
5335
struct xmit_frame *pmgntframe;
5336
struct pkt_attrib *pattrib;
5337
unsigned char *pframe;
5338
struct rtw_ieee80211_hdr *pwlanhdr;
5339
unsigned short *fctrl;
5340
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5341
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5342
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5343
5344
5345
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5346
if (pmgntframe == NULL)
5347
return;
5348
5349
RTW_INFO("[%s] In\n", __FUNCTION__);
5350
/* update attribute */
5351
pattrib = &pmgntframe->attrib;
5352
update_mgntframe_attrib(padapter, pattrib);
5353
5354
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5355
5356
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5357
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5358
5359
fctrl = &(pwlanhdr->frame_ctl);
5360
*(fctrl) = 0;
5361
5362
_rtw_memcpy(pwlanhdr->addr1, pdev_raddr, ETH_ALEN);
5363
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
5364
_rtw_memcpy(pwlanhdr->addr3, pdev_raddr, ETH_ALEN);
5365
5366
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5367
pmlmeext->mgnt_seq++;
5368
set_frame_sub_type(pframe, WIFI_ACTION);
5369
5370
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5371
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5372
5373
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
5374
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
5375
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *) &(p2poui), &(pattrib->pktlen));
5376
pframe = rtw_set_fixed_ie(pframe, 1, &(oui_subtype), &(pattrib->pktlen));
5377
pframe = rtw_set_fixed_ie(pframe, 1, &(dialogToken), &(pattrib->pktlen));
5378
5379
p2pielen = build_prov_disc_request_p2p_ie(pwdinfo, pframe, pssid, ussidlen, pdev_raddr);
5380
5381
pframe += p2pielen;
5382
pattrib->pktlen += p2pielen;
5383
5384
wpsielen = 0;
5385
/* WPS OUI */
5386
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5387
wpsielen += 4;
5388
5389
/* WPS version */
5390
/* Type: */
5391
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5392
wpsielen += 2;
5393
5394
/* Length: */
5395
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5396
wpsielen += 2;
5397
5398
/* Value: */
5399
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5400
5401
/* Config Method */
5402
/* Type: */
5403
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
5404
wpsielen += 2;
5405
5406
/* Length: */
5407
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5408
wpsielen += 2;
5409
5410
/* Value: */
5411
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->tx_prov_disc_info.wps_config_method_request);
5412
wpsielen += 2;
5413
5414
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
5415
5416
5417
#ifdef CONFIG_WFD
5418
wfdielen = build_provdisc_req_wfd_ie(pwdinfo, pframe);
5419
pframe += wfdielen;
5420
pattrib->pktlen += wfdielen;
5421
#endif
5422
5423
pattrib->last_txcmdsz = pattrib->pktlen;
5424
5425
dump_mgntframe(padapter, pmgntframe);
5426
5427
return;
5428
5429
}
5430
5431
5432
u8 is_matched_in_profilelist(u8 *peermacaddr, struct profile_info *profileinfo)
5433
{
5434
u8 i, match_result = 0;
5435
5436
RTW_INFO("[%s] peermac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5437
peermacaddr[0], peermacaddr[1], peermacaddr[2], peermacaddr[3], peermacaddr[4], peermacaddr[5]);
5438
5439
for (i = 0; i < P2P_MAX_PERSISTENT_GROUP_NUM; i++, profileinfo++) {
5440
RTW_INFO("[%s] profileinfo_mac = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
5441
profileinfo->peermac[0], profileinfo->peermac[1], profileinfo->peermac[2], profileinfo->peermac[3], profileinfo->peermac[4], profileinfo->peermac[5]);
5442
if (_rtw_memcmp(peermacaddr, profileinfo->peermac, ETH_ALEN)) {
5443
match_result = 1;
5444
RTW_INFO("[%s] Match!\n", __FUNCTION__);
5445
break;
5446
}
5447
}
5448
5449
return match_result ;
5450
}
5451
5452
void issue_probersp_p2p(_adapter *padapter, unsigned char *da)
5453
{
5454
struct xmit_frame *pmgntframe;
5455
struct pkt_attrib *pattrib;
5456
unsigned char *pframe;
5457
struct rtw_ieee80211_hdr *pwlanhdr;
5458
unsigned short *fctrl;
5459
unsigned char *mac;
5460
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5461
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5462
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5463
/* WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network); */
5464
u16 beacon_interval = 100;
5465
u16 capInfo = 0;
5466
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5467
u8 wpsie[255] = { 0x00 };
5468
u32 wpsielen = 0, p2pielen = 0;
5469
#ifdef CONFIG_WFD
5470
u32 wfdielen = 0;
5471
#endif
5472
5473
/* RTW_INFO("%s\n", __FUNCTION__); */
5474
5475
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5476
if (pmgntframe == NULL)
5477
return;
5478
5479
/* update attribute */
5480
pattrib = &pmgntframe->attrib;
5481
update_mgntframe_attrib(padapter, pattrib);
5482
5483
if (IS_CCK_RATE(pattrib->rate)) {
5484
/* force OFDM 6M rate */
5485
pattrib->rate = MGN_6M;
5486
pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
5487
}
5488
5489
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5490
5491
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5492
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5493
5494
mac = adapter_mac_addr(padapter);
5495
5496
fctrl = &(pwlanhdr->frame_ctl);
5497
*(fctrl) = 0;
5498
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5499
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5500
5501
/* Use the device address for BSSID field. */
5502
_rtw_memcpy(pwlanhdr->addr3, mac, ETH_ALEN);
5503
5504
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5505
pmlmeext->mgnt_seq++;
5506
set_frame_sub_type(fctrl, WIFI_PROBERSP);
5507
5508
pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5509
pattrib->pktlen = pattrib->hdrlen;
5510
pframe += pattrib->hdrlen;
5511
5512
/* timestamp will be inserted by hardware */
5513
pframe += 8;
5514
pattrib->pktlen += 8;
5515
5516
/* beacon interval: 2 bytes */
5517
_rtw_memcpy(pframe, (unsigned char *) &beacon_interval, 2);
5518
pframe += 2;
5519
pattrib->pktlen += 2;
5520
5521
/* capability info: 2 bytes */
5522
/* ESS and IBSS bits must be 0 (defined in the 3.1.2.1.1 of WiFi Direct Spec) */
5523
capInfo |= cap_ShortPremble;
5524
capInfo |= cap_ShortSlot;
5525
5526
_rtw_memcpy(pframe, (unsigned char *) &capInfo, 2);
5527
pframe += 2;
5528
pattrib->pktlen += 2;
5529
5530
5531
/* SSID */
5532
pframe = rtw_set_ie(pframe, _SSID_IE_, 7, pwdinfo->p2p_wildcard_ssid, &pattrib->pktlen);
5533
5534
/* supported rates... */
5535
/* Use the OFDM rate in the P2P probe response frame. ( 6(B), 9(B), 12, 18, 24, 36, 48, 54 ) */
5536
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5537
5538
/* DS parameter set */
5539
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&pwdinfo->listen_channel, &pattrib->pktlen);
5540
5541
#ifdef CONFIG_IOCTL_CFG80211
5542
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
5543
if (pmlmepriv->wps_probe_resp_ie != NULL && pmlmepriv->p2p_probe_resp_ie != NULL) {
5544
/* WPS IE */
5545
_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, pmlmepriv->wps_probe_resp_ie_len);
5546
pattrib->pktlen += pmlmepriv->wps_probe_resp_ie_len;
5547
pframe += pmlmepriv->wps_probe_resp_ie_len;
5548
5549
/* P2P IE */
5550
_rtw_memcpy(pframe, pmlmepriv->p2p_probe_resp_ie, pmlmepriv->p2p_probe_resp_ie_len);
5551
pattrib->pktlen += pmlmepriv->p2p_probe_resp_ie_len;
5552
pframe += pmlmepriv->p2p_probe_resp_ie_len;
5553
}
5554
} else
5555
#endif /* CONFIG_IOCTL_CFG80211 */
5556
{
5557
5558
/* Todo: WPS IE */
5559
/* Noted by Albert 20100907 */
5560
/* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
5561
5562
wpsielen = 0;
5563
/* WPS OUI */
5564
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5565
wpsielen += 4;
5566
5567
/* WPS version */
5568
/* Type: */
5569
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5570
wpsielen += 2;
5571
5572
/* Length: */
5573
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5574
wpsielen += 2;
5575
5576
/* Value: */
5577
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5578
5579
/* WiFi Simple Config State */
5580
/* Type: */
5581
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SIMPLE_CONF_STATE);
5582
wpsielen += 2;
5583
5584
/* Length: */
5585
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5586
wpsielen += 2;
5587
5588
/* Value: */
5589
wpsie[wpsielen++] = WPS_WSC_STATE_NOT_CONFIG; /* Not Configured. */
5590
5591
/* Response Type */
5592
/* Type: */
5593
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_RESP_TYPE);
5594
wpsielen += 2;
5595
5596
/* Length: */
5597
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5598
wpsielen += 2;
5599
5600
/* Value: */
5601
wpsie[wpsielen++] = WPS_RESPONSE_TYPE_8021X;
5602
5603
/* UUID-E */
5604
/* Type: */
5605
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
5606
wpsielen += 2;
5607
5608
/* Length: */
5609
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
5610
wpsielen += 2;
5611
5612
/* Value: */
5613
if (pwdinfo->external_uuid == 0) {
5614
_rtw_memset(wpsie + wpsielen, 0x0, 16);
5615
_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5616
} else
5617
_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
5618
wpsielen += 0x10;
5619
5620
/* Manufacturer */
5621
/* Type: */
5622
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MANUFACTURER);
5623
wpsielen += 2;
5624
5625
/* Length: */
5626
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0007);
5627
wpsielen += 2;
5628
5629
/* Value: */
5630
_rtw_memcpy(wpsie + wpsielen, "Realtek", 7);
5631
wpsielen += 7;
5632
5633
/* Model Name */
5634
/* Type: */
5635
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NAME);
5636
wpsielen += 2;
5637
5638
/* Length: */
5639
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0006);
5640
wpsielen += 2;
5641
5642
/* Value: */
5643
_rtw_memcpy(wpsie + wpsielen, "8192CU", 6);
5644
wpsielen += 6;
5645
5646
/* Model Number */
5647
/* Type: */
5648
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_MODEL_NUMBER);
5649
wpsielen += 2;
5650
5651
/* Length: */
5652
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5653
wpsielen += 2;
5654
5655
/* Value: */
5656
wpsie[wpsielen++] = 0x31; /* character 1 */
5657
5658
/* Serial Number */
5659
/* Type: */
5660
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_SERIAL_NUMBER);
5661
wpsielen += 2;
5662
5663
/* Length: */
5664
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(ETH_ALEN);
5665
wpsielen += 2;
5666
5667
/* Value: */
5668
_rtw_memcpy(wpsie + wpsielen, "123456" , ETH_ALEN);
5669
wpsielen += ETH_ALEN;
5670
5671
/* Primary Device Type */
5672
/* Type: */
5673
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5674
wpsielen += 2;
5675
5676
/* Length: */
5677
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5678
wpsielen += 2;
5679
5680
/* Value: */
5681
/* Category ID */
5682
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
5683
wpsielen += 2;
5684
5685
/* OUI */
5686
*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
5687
wpsielen += 4;
5688
5689
/* Sub Category ID */
5690
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
5691
wpsielen += 2;
5692
5693
/* Device Name */
5694
/* Type: */
5695
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5696
wpsielen += 2;
5697
5698
/* Length: */
5699
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
5700
wpsielen += 2;
5701
5702
/* Value: */
5703
_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
5704
wpsielen += pwdinfo->device_name_len;
5705
5706
/* Config Method */
5707
/* Type: */
5708
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
5709
wpsielen += 2;
5710
5711
/* Length: */
5712
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5713
wpsielen += 2;
5714
5715
/* Value: */
5716
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5717
wpsielen += 2;
5718
5719
5720
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
5721
5722
5723
p2pielen = build_probe_resp_p2p_ie(pwdinfo, pframe);
5724
pframe += p2pielen;
5725
pattrib->pktlen += p2pielen;
5726
}
5727
5728
#ifdef CONFIG_WFD
5729
wfdielen = rtw_append_probe_resp_wfd_ie(padapter, pframe);
5730
pframe += wfdielen;
5731
pattrib->pktlen += wfdielen;
5732
#endif
5733
5734
/* Vendor Specific IE */
5735
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
5736
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_P2P_PROBERESP_VENDOR_IE_BIT);
5737
#endif
5738
5739
pattrib->last_txcmdsz = pattrib->pktlen;
5740
5741
5742
dump_mgntframe(padapter, pmgntframe);
5743
5744
return;
5745
5746
}
5747
5748
int _issue_probereq_p2p(_adapter *padapter, u8 *da, int wait_ack)
5749
{
5750
int ret = _FAIL;
5751
struct xmit_frame *pmgntframe;
5752
struct pkt_attrib *pattrib;
5753
unsigned char *pframe;
5754
struct rtw_ieee80211_hdr *pwlanhdr;
5755
unsigned short *fctrl;
5756
unsigned char *mac;
5757
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
5758
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
5759
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
5760
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
5761
u8 wpsie[255] = { 0x00 }, p2pie[255] = { 0x00 };
5762
u16 wpsielen = 0, p2pielen = 0;
5763
#ifdef CONFIG_WFD
5764
u32 wfdielen = 0;
5765
#endif
5766
5767
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
5768
5769
5770
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
5771
if (pmgntframe == NULL)
5772
goto exit;
5773
5774
/* update attribute */
5775
pattrib = &pmgntframe->attrib;
5776
update_mgntframe_attrib(padapter, pattrib);
5777
5778
if (IS_CCK_RATE(pattrib->rate)) {
5779
/* force OFDM 6M rate */
5780
pattrib->rate = MGN_6M;
5781
pattrib->raid = rtw_get_mgntframe_raid(padapter, WIRELESS_11G);
5782
}
5783
5784
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
5785
5786
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
5787
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
5788
5789
mac = adapter_mac_addr(padapter);
5790
5791
fctrl = &(pwlanhdr->frame_ctl);
5792
*(fctrl) = 0;
5793
5794
if (da) {
5795
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
5796
_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
5797
} else {
5798
if ((pwdinfo->p2p_info.scan_op_ch_only) || (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
5799
/* This two flags will be set when this is only the P2P client mode. */
5800
_rtw_memcpy(pwlanhdr->addr1, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
5801
_rtw_memcpy(pwlanhdr->addr3, pwdinfo->p2p_peer_interface_addr, ETH_ALEN);
5802
} else {
5803
/* broadcast probe request frame */
5804
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
5805
_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
5806
}
5807
}
5808
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
5809
5810
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
5811
pmlmeext->mgnt_seq++;
5812
set_frame_sub_type(pframe, WIFI_PROBEREQ);
5813
5814
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
5815
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
5816
5817
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_TX_PROVISION_DIS_REQ))
5818
pframe = rtw_set_ie(pframe, _SSID_IE_, pwdinfo->tx_prov_disc_info.ssid.SsidLength, pwdinfo->tx_prov_disc_info.ssid.Ssid, &(pattrib->pktlen));
5819
else
5820
pframe = rtw_set_ie(pframe, _SSID_IE_, P2P_WILDCARD_SSID_LEN, pwdinfo->p2p_wildcard_ssid, &(pattrib->pktlen));
5821
/* Use the OFDM rate in the P2P probe request frame. ( 6(B), 9(B), 12(B), 24(B), 36, 48, 54 ) */
5822
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pwdinfo->support_rate, &pattrib->pktlen);
5823
5824
#ifdef CONFIG_IOCTL_CFG80211
5825
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
5826
if (pmlmepriv->wps_probe_req_ie != NULL && pmlmepriv->p2p_probe_req_ie != NULL) {
5827
/* WPS IE */
5828
_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
5829
pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
5830
pframe += pmlmepriv->wps_probe_req_ie_len;
5831
5832
/* P2P IE */
5833
_rtw_memcpy(pframe, pmlmepriv->p2p_probe_req_ie, pmlmepriv->p2p_probe_req_ie_len);
5834
pattrib->pktlen += pmlmepriv->p2p_probe_req_ie_len;
5835
pframe += pmlmepriv->p2p_probe_req_ie_len;
5836
}
5837
} else
5838
#endif /* CONFIG_IOCTL_CFG80211 */
5839
{
5840
5841
/* WPS IE */
5842
/* Noted by Albert 20110221 */
5843
/* According to the WPS specification, all the WPS attribute is presented by Big Endian. */
5844
5845
wpsielen = 0;
5846
/* WPS OUI */
5847
*(u32 *)(wpsie) = cpu_to_be32(WPSOUI);
5848
wpsielen += 4;
5849
5850
/* WPS version */
5851
/* Type: */
5852
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_VER1);
5853
wpsielen += 2;
5854
5855
/* Length: */
5856
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0001);
5857
wpsielen += 2;
5858
5859
/* Value: */
5860
wpsie[wpsielen++] = WPS_VERSION_1; /* Version 1.0 */
5861
5862
if (pmlmepriv->wps_probe_req_ie == NULL) {
5863
/* UUID-E */
5864
/* Type: */
5865
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_UUID_E);
5866
wpsielen += 2;
5867
5868
/* Length: */
5869
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0010);
5870
wpsielen += 2;
5871
5872
/* Value: */
5873
if (pwdinfo->external_uuid == 0) {
5874
_rtw_memset(wpsie + wpsielen, 0x0, 16);
5875
_rtw_memcpy(wpsie + wpsielen, mac, ETH_ALEN);
5876
} else
5877
_rtw_memcpy(wpsie + wpsielen, pwdinfo->uuid, 0x10);
5878
wpsielen += 0x10;
5879
5880
/* Config Method */
5881
/* Type: */
5882
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_CONF_METHOD);
5883
wpsielen += 2;
5884
5885
/* Length: */
5886
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5887
wpsielen += 2;
5888
5889
/* Value: */
5890
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->supported_wps_cm);
5891
wpsielen += 2;
5892
}
5893
5894
/* Device Name */
5895
/* Type: */
5896
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
5897
wpsielen += 2;
5898
5899
/* Length: */
5900
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(pwdinfo->device_name_len);
5901
wpsielen += 2;
5902
5903
/* Value: */
5904
_rtw_memcpy(wpsie + wpsielen, pwdinfo->device_name, pwdinfo->device_name_len);
5905
wpsielen += pwdinfo->device_name_len;
5906
5907
/* Primary Device Type */
5908
/* Type: */
5909
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
5910
wpsielen += 2;
5911
5912
/* Length: */
5913
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0008);
5914
wpsielen += 2;
5915
5916
/* Value: */
5917
/* Category ID */
5918
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_CID_RTK_WIDI);
5919
wpsielen += 2;
5920
5921
/* OUI */
5922
*(u32 *)(wpsie + wpsielen) = cpu_to_be32(WPSOUI);
5923
wpsielen += 4;
5924
5925
/* Sub Category ID */
5926
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_PDT_SCID_RTK_DMP);
5927
wpsielen += 2;
5928
5929
/* Device Password ID */
5930
/* Type: */
5931
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_ATTR_DEVICE_PWID);
5932
wpsielen += 2;
5933
5934
/* Length: */
5935
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(0x0002);
5936
wpsielen += 2;
5937
5938
/* Value: */
5939
*(u16 *)(wpsie + wpsielen) = cpu_to_be16(WPS_DPID_REGISTRAR_SPEC); /* Registrar-specified */
5940
wpsielen += 2;
5941
5942
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, wpsielen, (unsigned char *) wpsie, &pattrib->pktlen);
5943
5944
/* P2P OUI */
5945
p2pielen = 0;
5946
p2pie[p2pielen++] = 0x50;
5947
p2pie[p2pielen++] = 0x6F;
5948
p2pie[p2pielen++] = 0x9A;
5949
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
5950
5951
/* Commented by Albert 20110221 */
5952
/* According to the P2P Specification, the probe request frame should contain 5 P2P attributes */
5953
/* 1. P2P Capability */
5954
/* 2. P2P Device ID if this probe request wants to find the specific P2P device */
5955
/* 3. Listen Channel */
5956
/* 4. Extended Listen Timing */
5957
/* 5. Operating Channel if this WiFi is working as the group owner now */
5958
5959
/* P2P Capability */
5960
/* Type: */
5961
p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
5962
5963
/* Length: */
5964
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
5965
p2pielen += 2;
5966
5967
/* Value: */
5968
/* Device Capability Bitmap, 1 byte */
5969
p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
5970
5971
/* Group Capability Bitmap, 1 byte */
5972
if (pwdinfo->persistent_supported)
5973
p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
5974
else
5975
p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
5976
5977
/* Listen Channel */
5978
/* Type: */
5979
p2pie[p2pielen++] = P2P_ATTR_LISTEN_CH;
5980
5981
/* Length: */
5982
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
5983
p2pielen += 2;
5984
5985
/* Value: */
5986
/* Country String */
5987
p2pie[p2pielen++] = 'X';
5988
p2pie[p2pielen++] = 'X';
5989
5990
/* The third byte should be set to 0x04. */
5991
/* Described in the "Operating Channel Attribute" section. */
5992
p2pie[p2pielen++] = 0x04;
5993
5994
/* Operating Class */
5995
p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
5996
5997
/* Channel Number */
5998
p2pie[p2pielen++] = pwdinfo->listen_channel; /* listen channel */
5999
6000
6001
/* Extended Listen Timing */
6002
/* Type: */
6003
p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
6004
6005
/* Length: */
6006
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
6007
p2pielen += 2;
6008
6009
/* Value: */
6010
/* Availability Period */
6011
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6012
p2pielen += 2;
6013
6014
/* Availability Interval */
6015
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
6016
p2pielen += 2;
6017
6018
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
6019
/* Operating Channel (if this WiFi is working as the group owner now) */
6020
/* Type: */
6021
p2pie[p2pielen++] = P2P_ATTR_OPERATING_CH;
6022
6023
/* Length: */
6024
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0005);
6025
p2pielen += 2;
6026
6027
/* Value: */
6028
/* Country String */
6029
p2pie[p2pielen++] = 'X';
6030
p2pie[p2pielen++] = 'X';
6031
6032
/* The third byte should be set to 0x04. */
6033
/* Described in the "Operating Channel Attribute" section. */
6034
p2pie[p2pielen++] = 0x04;
6035
6036
/* Operating Class */
6037
p2pie[p2pielen++] = 0x51; /* Copy from SD7 */
6038
6039
/* Channel Number */
6040
p2pie[p2pielen++] = pwdinfo->operating_channel; /* operating channel number */
6041
6042
}
6043
6044
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
6045
6046
}
6047
6048
#ifdef CONFIG_WFD
6049
wfdielen = rtw_append_probe_req_wfd_ie(padapter, pframe);
6050
pframe += wfdielen;
6051
pattrib->pktlen += wfdielen;
6052
#endif
6053
6054
/* Vendor Specific IE */
6055
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
6056
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_P2P_PROBEREQ_VENDOR_IE_BIT);
6057
#endif
6058
6059
pattrib->last_txcmdsz = pattrib->pktlen;
6060
6061
6062
if (wait_ack)
6063
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
6064
else {
6065
dump_mgntframe(padapter, pmgntframe);
6066
ret = _SUCCESS;
6067
}
6068
6069
exit:
6070
return ret;
6071
}
6072
6073
inline void issue_probereq_p2p(_adapter *adapter, u8 *da)
6074
{
6075
_issue_probereq_p2p(adapter, da, _FALSE);
6076
}
6077
6078
/*
6079
* wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
6080
* wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
6081
* try_cnt means the maximal TX count to try
6082
*/
6083
int issue_probereq_p2p_ex(_adapter *adapter, u8 *da, int try_cnt, int wait_ms)
6084
{
6085
int ret;
6086
int i = 0;
6087
systime start = rtw_get_current_time();
6088
6089
do {
6090
ret = _issue_probereq_p2p(adapter, da, wait_ms > 0 ? _TRUE : _FALSE);
6091
6092
i++;
6093
6094
if (RTW_CANNOT_RUN(adapter))
6095
break;
6096
6097
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
6098
rtw_msleep_os(wait_ms);
6099
6100
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
6101
6102
if (ret != _FAIL) {
6103
ret = _SUCCESS;
6104
#ifndef DBG_XMIT_ACK
6105
goto exit;
6106
#endif
6107
}
6108
6109
if (try_cnt && wait_ms) {
6110
if (da)
6111
RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
6112
FUNC_ADPT_ARG(adapter), MAC_ARG(da), rtw_get_oper_ch(adapter),
6113
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6114
else
6115
RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
6116
FUNC_ADPT_ARG(adapter), rtw_get_oper_ch(adapter),
6117
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
6118
}
6119
exit:
6120
return ret;
6121
}
6122
6123
#endif /* CONFIG_P2P */
6124
6125
s32 rtw_action_public_decache(union recv_frame *rframe, u8 token_offset)
6126
{
6127
_adapter *adapter = rframe->u.hdr.adapter;
6128
struct mlme_ext_priv *mlmeext = &(adapter->mlmeextpriv);
6129
u8 *frame = rframe->u.hdr.rx_data;
6130
u16 seq_ctrl = ((rframe->u.hdr.attrib.seq_num & 0xffff) << 4) | (rframe->u.hdr.attrib.frag_num & 0xf);
6131
u8 token = *(rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + token_offset);
6132
6133
if (GetRetry(frame)) {
6134
if ((seq_ctrl == mlmeext->action_public_rxseq)
6135
&& (token == mlmeext->action_public_dialog_token)
6136
) {
6137
RTW_INFO(FUNC_ADPT_FMT" seq_ctrl=0x%x, rxseq=0x%x, token:%d\n",
6138
FUNC_ADPT_ARG(adapter), seq_ctrl, mlmeext->action_public_rxseq, token);
6139
return _FAIL;
6140
}
6141
}
6142
6143
/* TODO: per sta seq & token */
6144
mlmeext->action_public_rxseq = seq_ctrl;
6145
mlmeext->action_public_dialog_token = token;
6146
6147
return _SUCCESS;
6148
}
6149
6150
unsigned int on_action_public_p2p(union recv_frame *precv_frame)
6151
{
6152
_adapter *padapter = precv_frame->u.hdr.adapter;
6153
u8 *pframe = precv_frame->u.hdr.rx_data;
6154
uint len = precv_frame->u.hdr.len;
6155
u8 *frame_body;
6156
#ifdef CONFIG_P2P
6157
u8 *p2p_ie;
6158
u32 p2p_ielen;
6159
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
6160
u8 result = P2P_STATUS_SUCCESS;
6161
u8 empty_addr[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
6162
u8 *merged_p2pie = NULL;
6163
u32 merged_p2p_ielen = 0;
6164
#endif /* CONFIG_P2P */
6165
6166
frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
6167
6168
#ifdef CONFIG_P2P
6169
_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
6170
#ifdef CONFIG_IOCTL_CFG80211
6171
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211)
6172
rtw_cfg80211_rx_p2p_action_public(padapter, precv_frame);
6173
else
6174
#endif /* CONFIG_IOCTL_CFG80211 */
6175
{
6176
/* Do nothing if the driver doesn't enable the P2P function. */
6177
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) || rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE))
6178
return _SUCCESS;
6179
6180
len -= sizeof(struct rtw_ieee80211_hdr_3addr);
6181
6182
switch (frame_body[6]) { /* OUI Subtype */
6183
case P2P_GO_NEGO_REQ: {
6184
RTW_INFO("[%s] Got GO Nego Req Frame\n", __FUNCTION__);
6185
_rtw_memset(&pwdinfo->groupid_info, 0x00, sizeof(struct group_id_info));
6186
6187
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6188
rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6189
6190
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL)) {
6191
/* Commented by Albert 20110526 */
6192
/* In this case, this means the previous nego fail doesn't be reset yet. */
6193
_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6194
/* Restore the previous p2p state */
6195
rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
6196
RTW_INFO("[%s] Restore the previous p2p state to %d\n", __FUNCTION__, rtw_p2p_state(pwdinfo));
6197
}
6198
#ifdef CONFIG_CONCURRENT_MODE
6199
if (rtw_mi_buddy_check_fwstate(padapter, _FW_LINKED))
6200
_cancel_timer_ex(&pwdinfo->ap_p2p_switch_timer);
6201
#endif /* CONFIG_CONCURRENT_MODE */
6202
6203
/* Commented by Kurt 20110902 */
6204
/* Add if statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
6205
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING))
6206
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6207
6208
/* Commented by Kurt 20120113 */
6209
/* Get peer_dev_addr here if peer doesn't issue prov_disc frame. */
6210
if (_rtw_memcmp(pwdinfo->rx_prov_disc_info.peerDevAddr, empty_addr, ETH_ALEN))
6211
_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
6212
6213
result = process_p2p_group_negotation_req(pwdinfo, frame_body, len);
6214
issue_p2p_GO_response(padapter, get_addr2_ptr(pframe), frame_body, len, result);
6215
6216
/* Commented by Albert 20110718 */
6217
/* No matter negotiating or negotiation failure, the driver should set up the restore P2P state timer. */
6218
#ifdef CONFIG_CONCURRENT_MODE
6219
/* Commented by Albert 20120107 */
6220
_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
6221
#else /* CONFIG_CONCURRENT_MODE */
6222
_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
6223
#endif /* CONFIG_CONCURRENT_MODE */
6224
break;
6225
}
6226
case P2P_GO_NEGO_RESP: {
6227
RTW_INFO("[%s] Got GO Nego Resp Frame\n", __FUNCTION__);
6228
6229
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_ING)) {
6230
/* Commented by Albert 20110425 */
6231
/* The restore timer is enabled when issuing the nego request frame of rtw_p2p_connect function. */
6232
_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6233
pwdinfo->nego_req_info.benable = _FALSE;
6234
result = process_p2p_group_negotation_resp(pwdinfo, frame_body, len);
6235
issue_p2p_GO_confirm(pwdinfo->padapter, get_addr2_ptr(pframe), result);
6236
if (P2P_STATUS_SUCCESS == result) {
6237
if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
6238
pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
6239
#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6240
pwdinfo->p2p_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
6241
pwdinfo->p2p_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
6242
pwdinfo->p2p_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
6243
#endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
6244
pwdinfo->p2p_info.scan_op_ch_only = 1;
6245
_set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
6246
}
6247
}
6248
6249
/* Reset the dialog token for group negotiation frames. */
6250
pwdinfo->negotiation_dialog_token = 1;
6251
6252
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_GONEGO_FAIL))
6253
_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
6254
} else
6255
RTW_INFO("[%s] Skipped GO Nego Resp Frame (p2p_state != P2P_STATE_GONEGO_ING)\n", __FUNCTION__);
6256
6257
break;
6258
}
6259
case P2P_GO_NEGO_CONF: {
6260
RTW_INFO("[%s] Got GO Nego Confirm Frame\n", __FUNCTION__);
6261
result = process_p2p_group_negotation_confirm(pwdinfo, frame_body, len);
6262
if (P2P_STATUS_SUCCESS == result) {
6263
if (rtw_p2p_role(pwdinfo) == P2P_ROLE_CLIENT) {
6264
pwdinfo->p2p_info.operation_ch[0] = pwdinfo->peer_operating_ch;
6265
#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6266
pwdinfo->p2p_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
6267
pwdinfo->p2p_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
6268
pwdinfo->p2p_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
6269
#endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
6270
pwdinfo->p2p_info.scan_op_ch_only = 1;
6271
_set_timer(&pwdinfo->reset_ch_sitesurvey2, P2P_RESET_SCAN_CH);
6272
}
6273
}
6274
break;
6275
}
6276
case P2P_INVIT_REQ: {
6277
/* Added by Albert 2010/10/05 */
6278
/* Received the P2P Invite Request frame. */
6279
6280
RTW_INFO("[%s] Got invite request frame!\n", __FUNCTION__);
6281
p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
6282
if (p2p_ie) {
6283
/* Parse the necessary information from the P2P Invitation Request frame. */
6284
/* For example: The MAC address of sending this P2P Invitation Request frame. */
6285
u32 attr_contentlen = 0;
6286
u8 status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6287
struct group_id_info group_id;
6288
u8 invitation_flag = 0;
6289
6290
merged_p2p_ielen = rtw_get_p2p_merged_ies_len(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_);
6291
6292
merged_p2pie = rtw_zmalloc(merged_p2p_ielen + 2); /* 2 is for EID and Length */
6293
if (merged_p2pie == NULL) {
6294
RTW_INFO("[%s] Malloc p2p ie fail\n", __FUNCTION__);
6295
goto exit;
6296
}
6297
_rtw_memset(merged_p2pie, 0x00, merged_p2p_ielen);
6298
6299
merged_p2p_ielen = rtw_p2p_merge_ies(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, merged_p2pie);
6300
6301
rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_INVITATION_FLAGS, &invitation_flag, &attr_contentlen);
6302
if (attr_contentlen) {
6303
6304
rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_BSSID, pwdinfo->p2p_peer_interface_addr, &attr_contentlen);
6305
/* Commented by Albert 20120510 */
6306
/* Copy to the pwdinfo->p2p_peer_interface_addr. */
6307
/* So that the WFD UI ( or Sigma ) can get the peer interface address by using the following command. */
6308
/* #> iwpriv wlan0 p2p_get peer_ifa */
6309
/* After having the peer interface address, the sigma can find the correct conf file for wpa_supplicant. */
6310
6311
if (attr_contentlen) {
6312
RTW_INFO("[%s] GO's BSSID = %.2X %.2X %.2X %.2X %.2X %.2X\n", __FUNCTION__,
6313
pwdinfo->p2p_peer_interface_addr[0], pwdinfo->p2p_peer_interface_addr[1],
6314
pwdinfo->p2p_peer_interface_addr[2], pwdinfo->p2p_peer_interface_addr[3],
6315
pwdinfo->p2p_peer_interface_addr[4], pwdinfo->p2p_peer_interface_addr[5]);
6316
}
6317
6318
if (invitation_flag & P2P_INVITATION_FLAGS_PERSISTENT) {
6319
/* Re-invoke the persistent group. */
6320
6321
_rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
6322
rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
6323
if (attr_contentlen) {
6324
if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
6325
/* The p2p device sending this p2p invitation request wants this Wi-Fi device to be the persistent GO. */
6326
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_GO);
6327
rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
6328
status_code = P2P_STATUS_SUCCESS;
6329
} else {
6330
/* The p2p device sending this p2p invitation request wants to be the persistent GO. */
6331
if (is_matched_in_profilelist(pwdinfo->p2p_peer_interface_addr, &pwdinfo->profileinfo[0])) {
6332
u8 operatingch_info[5] = { 0x00 };
6333
if (rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_OPERATING_CH, operatingch_info,
6334
&attr_contentlen)) {
6335
if (rtw_chset_search_ch(adapter_to_chset(padapter), (u32)operatingch_info[4]) >= 0) {
6336
/* The operating channel is acceptable for this device. */
6337
pwdinfo->rx_invitereq_info.operation_ch[0] = operatingch_info[4];
6338
#ifdef CONFIG_P2P_OP_CHK_SOCIAL_CH
6339
pwdinfo->rx_invitereq_info.operation_ch[1] = 1; /* Check whether GO is operating in channel 1; */
6340
pwdinfo->rx_invitereq_info.operation_ch[2] = 6; /* Check whether GO is operating in channel 6; */
6341
pwdinfo->rx_invitereq_info.operation_ch[3] = 11; /* Check whether GO is operating in channel 11; */
6342
#endif /* CONFIG_P2P_OP_CHK_SOCIAL_CH */
6343
pwdinfo->rx_invitereq_info.scan_op_ch_only = 1;
6344
_set_timer(&pwdinfo->reset_ch_sitesurvey, P2P_RESET_SCAN_CH);
6345
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
6346
rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6347
status_code = P2P_STATUS_SUCCESS;
6348
} else {
6349
/* The operating channel isn't supported by this device. */
6350
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
6351
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6352
status_code = P2P_STATUS_FAIL_NO_COMMON_CH;
6353
_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
6354
}
6355
} else {
6356
/* Commented by Albert 20121130 */
6357
/* Intel will use the different P2P IE to store the operating channel information */
6358
/* Workaround for Intel WiDi 3.5 */
6359
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_MATCH);
6360
rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6361
status_code = P2P_STATUS_SUCCESS;
6362
}
6363
} else {
6364
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
6365
status_code = P2P_STATUS_FAIL_UNKNOWN_P2PGROUP;
6366
}
6367
}
6368
} else {
6369
RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
6370
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6371
}
6372
} else {
6373
/* Received the invitation to join a P2P group. */
6374
6375
_rtw_memset(&group_id, 0x00, sizeof(struct group_id_info));
6376
rtw_get_p2p_attr_content(merged_p2pie, merged_p2p_ielen, P2P_ATTR_GROUP_ID, (u8 *) &group_id, &attr_contentlen);
6377
if (attr_contentlen) {
6378
if (_rtw_memcmp(group_id.go_device_addr, adapter_mac_addr(padapter), ETH_ALEN)) {
6379
/* In this case, the GO can't be myself. */
6380
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_DISMATCH);
6381
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6382
} else {
6383
/* The p2p device sending this p2p invitation request wants to join an existing P2P group */
6384
/* Commented by Albert 2012/06/28 */
6385
/* In this case, this Wi-Fi device should use the iwpriv command to get the peer device address. */
6386
/* The peer device address should be the destination address for the provisioning discovery request. */
6387
/* Then, this Wi-Fi device should use the iwpriv command to get the peer interface address. */
6388
/* The peer interface address should be the address for WPS mac address */
6389
_rtw_memcpy(pwdinfo->p2p_peer_device_addr, group_id.go_device_addr , ETH_ALEN);
6390
rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6391
rtw_p2p_set_state(pwdinfo, P2P_STATE_RECV_INVITE_REQ_JOIN);
6392
status_code = P2P_STATUS_SUCCESS;
6393
}
6394
} else {
6395
RTW_INFO("[%s] P2P Group ID Attribute NOT FOUND!\n", __FUNCTION__);
6396
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6397
}
6398
}
6399
} else {
6400
RTW_INFO("[%s] P2P Invitation Flags Attribute NOT FOUND!\n", __FUNCTION__);
6401
status_code = P2P_STATUS_FAIL_INFO_UNAVAILABLE;
6402
}
6403
6404
RTW_INFO("[%s] status_code = %d\n", __FUNCTION__, status_code);
6405
6406
pwdinfo->inviteresp_info.token = frame_body[7];
6407
issue_p2p_invitation_response(padapter, get_addr2_ptr(pframe), pwdinfo->inviteresp_info.token, status_code);
6408
_set_timer(&pwdinfo->restore_p2p_state_timer, 3000);
6409
}
6410
break;
6411
}
6412
case P2P_INVIT_RESP: {
6413
u8 attr_content = 0x00;
6414
u32 attr_contentlen = 0;
6415
6416
RTW_INFO("[%s] Got invite response frame!\n", __FUNCTION__);
6417
_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6418
p2p_ie = rtw_get_p2p_ie(frame_body + _PUBLIC_ACTION_IE_OFFSET_, len - _PUBLIC_ACTION_IE_OFFSET_, NULL, &p2p_ielen);
6419
if (p2p_ie) {
6420
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_STATUS, &attr_content, &attr_contentlen);
6421
6422
if (attr_contentlen == 1) {
6423
RTW_INFO("[%s] Status = %d\n", __FUNCTION__, attr_content);
6424
pwdinfo->invitereq_info.benable = _FALSE;
6425
6426
if (attr_content == P2P_STATUS_SUCCESS) {
6427
if (_rtw_memcmp(pwdinfo->invitereq_info.go_bssid, adapter_mac_addr(padapter), ETH_ALEN))
6428
rtw_p2p_set_role(pwdinfo, P2P_ROLE_GO);
6429
else
6430
rtw_p2p_set_role(pwdinfo, P2P_ROLE_CLIENT);
6431
6432
rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_OK);
6433
} else {
6434
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6435
rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
6436
}
6437
} else {
6438
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6439
rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
6440
}
6441
} else {
6442
rtw_p2p_set_role(pwdinfo, P2P_ROLE_DEVICE);
6443
rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL);
6444
}
6445
6446
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_INVITE_RESP_FAIL))
6447
_set_timer(&pwdinfo->restore_p2p_state_timer, 5000);
6448
break;
6449
}
6450
case P2P_DEVDISC_REQ:
6451
6452
process_p2p_devdisc_req(pwdinfo, pframe, len);
6453
6454
break;
6455
6456
case P2P_DEVDISC_RESP:
6457
6458
process_p2p_devdisc_resp(pwdinfo, pframe, len);
6459
6460
break;
6461
6462
case P2P_PROVISION_DISC_REQ:
6463
RTW_INFO("[%s] Got Provisioning Discovery Request Frame\n", __FUNCTION__);
6464
process_p2p_provdisc_req(pwdinfo, pframe, len);
6465
_rtw_memcpy(pwdinfo->rx_prov_disc_info.peerDevAddr, get_addr2_ptr(pframe), ETH_ALEN);
6466
6467
/* 20110902 Kurt */
6468
/* Add the following statement to avoid receiving duplicate prov disc req. such that pre_p2p_state would be covered. */
6469
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ))
6470
rtw_p2p_set_pre_state(pwdinfo, rtw_p2p_state(pwdinfo));
6471
6472
rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_REQ);
6473
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
6474
break;
6475
6476
case P2P_PROVISION_DISC_RESP:
6477
/* Commented by Albert 20110707 */
6478
/* Should we check the pwdinfo->tx_prov_disc_info.bsent flag here?? */
6479
RTW_INFO("[%s] Got Provisioning Discovery Response Frame\n", __FUNCTION__);
6480
/* Commented by Albert 20110426 */
6481
/* The restore timer is enabled when issuing the provisioing request frame in rtw_p2p_prov_disc function. */
6482
_cancel_timer_ex(&pwdinfo->restore_p2p_state_timer);
6483
rtw_p2p_set_state(pwdinfo, P2P_STATE_RX_PROVISION_DIS_RSP);
6484
process_p2p_provdisc_resp(pwdinfo, pframe);
6485
_set_timer(&pwdinfo->restore_p2p_state_timer, P2P_PROVISION_TIMEOUT);
6486
break;
6487
6488
}
6489
}
6490
6491
6492
exit:
6493
6494
if (merged_p2pie)
6495
rtw_mfree(merged_p2pie, merged_p2p_ielen + 2);
6496
#endif /* CONFIG_P2P */
6497
return _SUCCESS;
6498
}
6499
6500
unsigned int on_action_public_vendor(union recv_frame *precv_frame)
6501
{
6502
unsigned int ret = _FAIL;
6503
u8 *pframe = precv_frame->u.hdr.rx_data;
6504
u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6505
6506
if (_rtw_memcmp(frame_body + 2, P2P_OUI, 4) == _TRUE) {
6507
if (rtw_action_public_decache(precv_frame, 7) == _FAIL)
6508
goto exit;
6509
6510
if (!hal_chk_wl_func(precv_frame->u.hdr.adapter, WL_FUNC_MIRACAST))
6511
rtw_rframe_del_wfd_ie(precv_frame, 8);
6512
6513
ret = on_action_public_p2p(precv_frame);
6514
}
6515
6516
exit:
6517
return ret;
6518
}
6519
6520
unsigned int on_action_public_default(union recv_frame *precv_frame, u8 action)
6521
{
6522
unsigned int ret = _FAIL;
6523
u8 *pframe = precv_frame->u.hdr.rx_data;
6524
u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6525
u8 token;
6526
_adapter *adapter = precv_frame->u.hdr.adapter;
6527
int cnt = 0;
6528
char msg[64];
6529
6530
token = frame_body[2];
6531
6532
if (rtw_action_public_decache(precv_frame, 2) == _FAIL)
6533
goto exit;
6534
6535
#ifdef CONFIG_IOCTL_CFG80211
6536
cnt += sprintf((msg + cnt), "%s(token:%u)", action_public_str(action), token);
6537
rtw_cfg80211_rx_action(adapter, precv_frame, msg);
6538
#endif
6539
6540
ret = _SUCCESS;
6541
6542
exit:
6543
return ret;
6544
}
6545
6546
unsigned int on_action_public(_adapter *padapter, union recv_frame *precv_frame)
6547
{
6548
unsigned int ret = _FAIL;
6549
u8 *pframe = precv_frame->u.hdr.rx_data;
6550
uint frame_len = precv_frame->u.hdr.len;
6551
u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6552
u8 category, action;
6553
6554
/* check RA matches or not */
6555
if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
6556
goto exit;
6557
6558
category = frame_body[0];
6559
if (category != RTW_WLAN_CATEGORY_PUBLIC)
6560
goto exit;
6561
6562
action = frame_body[1];
6563
switch (action) {
6564
case ACT_PUBLIC_BSSCOEXIST:
6565
#ifdef CONFIG_80211N_HT
6566
#ifdef CONFIG_AP_MODE
6567
/*20/40 BSS Coexistence Management frame is a Public Action frame*/
6568
if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6569
rtw_process_public_act_bsscoex(padapter, pframe, frame_len);
6570
#endif /*CONFIG_AP_MODE*/
6571
#endif /*CONFIG_80211N_HT*/
6572
break;
6573
case ACT_PUBLIC_VENDOR:
6574
ret = on_action_public_vendor(precv_frame);
6575
break;
6576
default:
6577
ret = on_action_public_default(precv_frame, action);
6578
break;
6579
}
6580
6581
exit:
6582
return ret;
6583
}
6584
6585
#if defined(CONFIG_RTW_WNM) || defined(CONFIG_RTW_80211K)
6586
static u8 rtw_wnm_nb_elem_parsing(
6587
u8* pdata, u32 data_len, u8 from_btm,
6588
u32 *nb_rpt_num, u8 *nb_rpt_is_same,
6589
struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates)
6590
{
6591
u8 bfound = _FALSE, ret = _SUCCESS;
6592
u8 *ptr, *pend, *op;
6593
u32 elem_len, subelem_len, op_len;
6594
u32 i, nb_rpt_entries = 0;
6595
struct nb_rpt_hdr *pie;
6596
struct wnm_btm_cant *pcandidate;
6597
6598
if ((!pdata) || (!pnb))
6599
return _FAIL;
6600
6601
if ((from_btm) && (!pcandidates))
6602
return _FAIL;
6603
6604
ptr = pdata;
6605
pend = ptr + data_len;
6606
elem_len = data_len;
6607
subelem_len = (u32)*(pdata+1);
6608
6609
for (i=0; i < RTW_MAX_NB_RPT_NUM; i++) {
6610
if (((ptr + 7) > pend) || (elem_len < subelem_len))
6611
break;
6612
6613
if (*ptr != 0x34) {
6614
RTW_ERR("WNM: invalid data(0x%2x)!\n", *ptr);
6615
ret = _FAIL;
6616
break;
6617
}
6618
6619
pie = (struct nb_rpt_hdr *)ptr;
6620
if (from_btm) {
6621
op = rtw_get_ie((u8 *)(ptr+15),
6622
WNM_BTM_CAND_PREF_SUBEID,
6623
&op_len, (subelem_len - 15));
6624
}
6625
6626
ptr = (u8 *)(ptr + subelem_len + 2);
6627
elem_len -= (subelem_len +2);
6628
subelem_len = *(ptr+1);
6629
if (from_btm) {
6630
pcandidate = (pcandidates + i);
6631
_rtw_memcpy(&pcandidate->nb_rpt, pie, sizeof(struct nb_rpt_hdr));
6632
if (op && (op_len !=0)) {
6633
pcandidate->preference = *(op + 2);
6634
bfound = _TRUE;
6635
} else
6636
pcandidate->preference = 0;
6637
6638
RTW_DBG("WNM: preference check bssid("MAC_FMT
6639
") ,bss_info(0x%04X), reg_class(0x%02X), ch(%d),"
6640
" phy_type(0x%02X), preference(0x%02X)\n",
6641
MAC_ARG(pcandidate->nb_rpt.bssid), pcandidate->nb_rpt.bss_info,
6642
pcandidate->nb_rpt.reg_class, pcandidate->nb_rpt.ch_num,
6643
pcandidate->nb_rpt.phy_type, pcandidate->preference);
6644
} else {
6645
if (_rtw_memcmp(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr)) == _FALSE)
6646
*nb_rpt_is_same = _FALSE;
6647
_rtw_memcpy(&pnb->nb_rpt[i], pie, sizeof(struct nb_rpt_hdr));
6648
}
6649
nb_rpt_entries++;
6650
}
6651
6652
if (from_btm)
6653
pnb->preference_en = (bfound)?_TRUE:_FALSE;
6654
6655
*nb_rpt_num = nb_rpt_entries;
6656
return ret;
6657
}
6658
6659
/* selection sorting based on preference value
6660
* : nb_rpt_entries - candidate num
6661
* / : pcandidates - candidate list
6662
* return : TRUE - means pcandidates is updated.
6663
*/
6664
static u8 rtw_wnm_candidates_sorting(
6665
u32 nb_rpt_entries, struct wnm_btm_cant *pcandidates)
6666
{
6667
u8 updated = _FALSE;
6668
u32 i, j, pos;
6669
struct wnm_btm_cant swap;
6670
struct wnm_btm_cant *pcant_1, *pcant_2;
6671
6672
if ((!nb_rpt_entries) || (!pcandidates))
6673
return updated;
6674
6675
for (i=0; i < (nb_rpt_entries - 1); i++) {
6676
pos = i;
6677
for (j=(i + 1); j < nb_rpt_entries; j++) {
6678
pcant_1 = pcandidates+pos;
6679
pcant_2 = pcandidates+j;
6680
if ((pcant_1->preference) < (pcant_2->preference))
6681
pos = j;
6682
}
6683
6684
if (pos != i) {
6685
updated = _TRUE;
6686
_rtw_memcpy(&swap, (pcandidates+i), sizeof(struct wnm_btm_cant));
6687
_rtw_memcpy((pcandidates+i), (pcandidates+pos), sizeof(struct wnm_btm_cant));
6688
_rtw_memcpy((pcandidates+pos), &swap, sizeof(struct wnm_btm_cant));
6689
}
6690
}
6691
return updated;
6692
}
6693
6694
static void rtw_wnm_nb_info_update(
6695
u32 nb_rpt_entries, u8 from_btm,
6696
struct roam_nb_info *pnb, struct wnm_btm_cant *pcandidates,
6697
u8 *nb_rpt_is_same)
6698
{
6699
u8 is_found;
6700
u32 i, j;
6701
struct wnm_btm_cant *pcand;
6702
6703
if (!pnb)
6704
return;
6705
6706
pnb->nb_rpt_ch_list_num = 0;
6707
for (i=0; i<nb_rpt_entries; i++) {
6708
is_found = _FALSE;
6709
if (from_btm) {
6710
pcand = (pcandidates+i);
6711
if (_rtw_memcmp(&pnb->nb_rpt[i], &pcand->nb_rpt,
6712
sizeof(struct nb_rpt_hdr)) == _FALSE)
6713
*nb_rpt_is_same = _FALSE;
6714
_rtw_memcpy(&pnb->nb_rpt[i], &pcand->nb_rpt, sizeof(struct nb_rpt_hdr));
6715
}
6716
6717
RTW_DBG("WNM: bssid(" MAC_FMT
6718
") , bss_info(0x%04X), reg_class(0x%02X), ch_num(%d), phy_type(0x%02X)\n",
6719
MAC_ARG(pnb->nb_rpt[i].bssid), pnb->nb_rpt[i].bss_info,
6720
pnb->nb_rpt[i].reg_class, pnb->nb_rpt[i].ch_num,
6721
pnb->nb_rpt[i].phy_type);
6722
6723
if (pnb->nb_rpt[i].ch_num == 0)
6724
continue;
6725
6726
for (j=0; j<nb_rpt_entries; j++) {
6727
if (pnb->nb_rpt[i].ch_num == pnb->nb_rpt_ch_list[j].hw_value) {
6728
is_found = _TRUE;
6729
break;
6730
}
6731
}
6732
6733
if (!is_found) {
6734
pnb->nb_rpt_ch_list[pnb->nb_rpt_ch_list_num].hw_value = pnb->nb_rpt[i].ch_num;
6735
pnb->nb_rpt_ch_list_num++;
6736
}
6737
}
6738
}
6739
6740
static void rtw_wnm_btm_candidate_select(_adapter *padapter)
6741
{
6742
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
6743
struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info);
6744
struct wlan_network *pnetwork;
6745
u8 bfound = _FALSE;
6746
u32 i;
6747
6748
for (i = 0; i < pnb->last_nb_rpt_entries; i++) {
6749
pnetwork = rtw_find_network(
6750
&(pmlmepriv->scanned_queue),
6751
pnb->nb_rpt[i].bssid);
6752
6753
if (pnetwork) {
6754
bfound = _TRUE;
6755
break;
6756
}
6757
}
6758
6759
if (bfound) {
6760
_rtw_memcpy(pnb->roam_target_addr, pnb->nb_rpt[i].bssid, ETH_ALEN);
6761
RTW_INFO("WNM : select btm entry(%d) - %s("MAC_FMT", ch%u) rssi:%d\n"
6762
, i
6763
, pnetwork->network.Ssid.Ssid
6764
, MAC_ARG(pnetwork->network.MacAddress)
6765
, pnetwork->network.Configuration.DSConfig
6766
, (int)pnetwork->network.Rssi);
6767
} else
6768
_rtw_memset(pnb->roam_target_addr,0, ETH_ALEN);
6769
}
6770
6771
u32 rtw_wnm_btm_candidates_survey(
6772
_adapter *padapter, u8* pframe, u32 elem_len, u8 from_btm)
6773
{
6774
struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info);
6775
struct wnm_btm_cant *pcandidate_list = NULL;
6776
u8 nb_rpt_is_same = _TRUE;
6777
u32 ret = _FAIL;
6778
u32 nb_rpt_entries = 0;
6779
6780
if (from_btm) {
6781
u32 mlen = sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM;
6782
pcandidate_list = (struct wnm_btm_cant *)rtw_malloc(mlen);
6783
if (pcandidate_list == NULL)
6784
goto exit;
6785
}
6786
6787
/*clean the status set last time*/
6788
_rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list));
6789
pnb->nb_rpt_valid = _FALSE;
6790
if (!rtw_wnm_nb_elem_parsing(
6791
pframe, elem_len, from_btm,
6792
&nb_rpt_entries, &nb_rpt_is_same,
6793
pnb, pcandidate_list))
6794
goto exit;
6795
6796
if (nb_rpt_entries != 0) {
6797
if ((from_btm) && (rtw_wnm_btm_preference_cap(padapter)))
6798
rtw_wnm_candidates_sorting(nb_rpt_entries, pcandidate_list);
6799
6800
rtw_wnm_nb_info_update(
6801
nb_rpt_entries, from_btm,
6802
pnb, pcandidate_list, &nb_rpt_is_same);
6803
}
6804
6805
RTW_INFO("nb_rpt_is_same = %d, nb_rpt_entries = %d, last_nb_rpt_entries = %d\n",
6806
nb_rpt_is_same, nb_rpt_entries, pnb->last_nb_rpt_entries);
6807
if ((nb_rpt_is_same == _TRUE) && (nb_rpt_entries == pnb->last_nb_rpt_entries))
6808
pnb->nb_rpt_is_same = _TRUE;
6809
else {
6810
pnb->nb_rpt_is_same = _FALSE;
6811
pnb->last_nb_rpt_entries = nb_rpt_entries;
6812
}
6813
6814
if ((from_btm) && (nb_rpt_entries != 0))
6815
rtw_wnm_btm_candidate_select(padapter);
6816
6817
pnb->nb_rpt_valid = _TRUE;
6818
ret = _SUCCESS;
6819
6820
exit:
6821
if (from_btm && pcandidate_list)
6822
rtw_mfree((u8 *)pcandidate_list, sizeof(struct wnm_btm_cant) * RTW_MAX_NB_RPT_NUM);
6823
6824
return ret;
6825
}
6826
#endif
6827
6828
unsigned int OnAction_ft(_adapter *padapter, union recv_frame *precv_frame)
6829
{
6830
#ifdef CONFIG_RTW_80211R
6831
u32 ret = _FAIL;
6832
u32 frame_len = 0;
6833
u8 action_code = 0;
6834
u8 category = 0;
6835
u8 *pframe = NULL;
6836
u8 *pframe_body = NULL;
6837
u8 sta_addr[ETH_ALEN] = {0};
6838
u8 *pie = NULL;
6839
u32 ft_ie_len = 0;
6840
u32 status_code = 0;
6841
struct mlme_ext_priv *pmlmeext = NULL;
6842
struct mlme_ext_info *pmlmeinfo = NULL;
6843
struct mlme_priv *pmlmepriv = NULL;
6844
struct wlan_network *proam_target = NULL;
6845
struct ft_roam_info *pft_roam = NULL;
6846
_irqL irqL;
6847
6848
pmlmeext = &(padapter->mlmeextpriv);
6849
pmlmeinfo = &(pmlmeext->mlmext_info);
6850
pmlmepriv = &(padapter->mlmepriv);
6851
pft_roam = &(pmlmepriv->ft_roam);
6852
pframe = precv_frame->u.hdr.rx_data;
6853
frame_len = precv_frame->u.hdr.len;
6854
pframe_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
6855
category = pframe_body[0];
6856
6857
if (category != RTW_WLAN_CATEGORY_FT)
6858
goto exit;
6859
6860
action_code = pframe_body[1];
6861
switch (action_code) {
6862
case RTW_WLAN_ACTION_FT_RSP:
6863
RTW_INFO("FT: RTW_WLAN_ACTION_FT_RSP recv.\n");
6864
if (!_rtw_memcmp(adapter_mac_addr(padapter), &pframe_body[2], ETH_ALEN)) {
6865
RTW_ERR("FT: Unmatched STA MAC Address "MAC_FMT"\n", MAC_ARG(&pframe_body[2]));
6866
goto exit;
6867
}
6868
6869
status_code = le16_to_cpu(*(u16 *)((SIZE_PTR)pframe + sizeof(struct rtw_ieee80211_hdr_3addr) + 14));
6870
if (status_code != 0) {
6871
RTW_ERR("FT: WLAN ACTION FT RESPONSE fail, status: %d\n", status_code);
6872
goto exit;
6873
}
6874
6875
if (is_zero_mac_addr(&pframe_body[8]) || is_broadcast_mac_addr(&pframe_body[8])) {
6876
RTW_ERR("FT: Invalid Target MAC Address "MAC_FMT"\n", MAC_ARG(padapter->mlmepriv.roam_tgt_addr));
6877
goto exit;
6878
}
6879
6880
pie = rtw_get_ie(pframe_body, _MDIE_, &ft_ie_len, frame_len);
6881
if (pie) {
6882
if (!_rtw_memcmp(&pft_roam->mdid, pie+2, 2)) {
6883
RTW_ERR("FT: Invalid MDID\n");
6884
goto exit;
6885
}
6886
}
6887
6888
rtw_ft_set_status(padapter, RTW_FT_REQUESTED_STA);
6889
_cancel_timer_ex(&pmlmeext->ft_link_timer);
6890
6891
/*Disconnect current AP*/
6892
receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress, WLAN_REASON_ACTIVE_ROAM, _FALSE);
6893
6894
pft_roam->ft_action_len = frame_len;
6895
_rtw_memcpy(pft_roam->ft_action, pframe, rtw_min(frame_len, RTW_FT_MAX_IE_SZ));
6896
ret = _SUCCESS;
6897
break;
6898
case RTW_WLAN_ACTION_FT_REQ:
6899
case RTW_WLAN_ACTION_FT_CONF:
6900
case RTW_WLAN_ACTION_FT_ACK:
6901
default:
6902
RTW_ERR("FT: Unsupported FT Action!\n");
6903
break;
6904
}
6905
6906
exit:
6907
return ret;
6908
#else
6909
return _SUCCESS;
6910
#endif
6911
}
6912
6913
#ifdef CONFIG_RTW_WNM
6914
u8 rtw_wmn_btm_rsp_reason_decision(_adapter *padapter, u8* req_mode)
6915
{
6916
struct recv_priv *precvpriv = &padapter->recvpriv;
6917
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
6918
u8 reason = 0;
6919
6920
if (!rtw_wnm_btm_diff_bss(padapter)) {
6921
/* Reject - No suitable BSS transition candidates */
6922
reason = 7;
6923
goto candidate_remove;
6924
}
6925
6926
#ifdef CONFIG_RTW_80211R
6927
if (rtw_ft_chk_flags(padapter, RTW_FT_BTM_ROAM)) {
6928
/* Accept */
6929
reason = 0;
6930
goto under_survey;
6931
}
6932
#endif
6933
6934
if (((*req_mode) & DISASSOC_IMMINENT) == 0) {
6935
/* Reject - Unspecified reject reason */
6936
reason = 1;
6937
goto candidate_remove;
6938
}
6939
6940
if (precvpriv->signal_strength_data.avg_val >= pmlmepriv->roam_rssi_threshold) {
6941
reason = 1;
6942
goto candidate_remove;
6943
}
6944
6945
under_survey:
6946
if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) {
6947
RTW_INFO("%s reject due to _FW_UNDER_SURVEY\n", __func__);
6948
reason = 1;
6949
}
6950
6951
candidate_remove:
6952
if (reason !=0)
6953
rtw_wnm_reset_btm_candidate(&padapter->mlmepriv.nb_info);
6954
6955
return reason;
6956
}
6957
6958
static u32 rtw_wnm_btm_candidates_offset_get(u8* pframe)
6959
{
6960
u8 *pos = pframe;
6961
u32 offset = 0;
6962
6963
if (!pframe)
6964
return 0;
6965
6966
offset += 7;
6967
pos += offset;
6968
6969
/* BSS Termination Duration check */
6970
if (wnm_btm_bss_term_inc(pframe)) {
6971
offset += 12;
6972
pos += offset;
6973
}
6974
6975
/* Session Information URL check*/
6976
if (wnm_btm_ess_disassoc_im(pframe)) {
6977
/*URL length field + URL variable length*/
6978
offset = 1 + *(pframe + offset);
6979
pos += offset;
6980
}
6981
6982
offset = (pos - pframe);
6983
return offset;
6984
}
6985
6986
static void rtw_wnm_btm_req_hdr_parsing(u8* pframe, struct btm_req_hdr *phdr)
6987
{
6988
u8 *pos = pframe;
6989
u32 offset = 0;
6990
6991
if (!pframe || !phdr)
6992
return;
6993
6994
_rtw_memset(phdr, 0, sizeof(struct btm_req_hdr));
6995
phdr->req_mode = wnm_btm_req_mode(pframe);
6996
phdr->disassoc_timer = wnm_btm_disassoc_timer(pframe);
6997
phdr->validity_interval = wnm_btm_valid_interval(pframe);
6998
if (wnm_btm_bss_term_inc(pframe)) {
6999
_rtw_memcpy(&phdr->term_duration,
7000
wnm_btm_term_duration_offset(pframe),
7001
sizeof(struct btm_term_duration));
7002
}
7003
7004
RTW_DBG("WNM: req_mode(%1x), disassoc_timer(%02x), interval(%x)\n",
7005
phdr->req_mode, phdr->disassoc_timer, phdr->validity_interval);
7006
if (wnm_btm_bss_term_inc(pframe))
7007
RTW_INFO("WNM: tsf(%llx), duration(%2x)\n",
7008
phdr->term_duration.tsf, phdr->term_duration.duration);
7009
}
7010
7011
void rtw_wnm_roam_scan_hdl(void *ctx)
7012
{
7013
_adapter *padapter = (_adapter *)ctx;
7014
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7015
7016
if (rtw_is_scan_deny(padapter))
7017
RTW_INFO("WNM: roam scan would abort by scan_deny!\n");
7018
7019
pmlmepriv->need_to_roam = _TRUE;
7020
rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM);
7021
}
7022
7023
static void rtw_wnm_roam_scan(_adapter *padapter)
7024
{
7025
struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info);
7026
7027
if (rtw_is_scan_deny(padapter)) {
7028
_cancel_timer_ex(&pnb->roam_scan_timer);
7029
_set_timer(&pnb->roam_scan_timer, 1000);
7030
} else
7031
rtw_wnm_roam_scan_hdl((void *)padapter);
7032
}
7033
7034
void rtw_wnm_process_btm_req(_adapter *padapter, u8* pframe, u32 frame_len)
7035
{
7036
struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info);
7037
struct btm_req_hdr req_hdr;
7038
u8 *ptr, reason;
7039
u32 elem_len, offset;
7040
7041
rtw_wnm_btm_req_hdr_parsing(pframe, &req_hdr);
7042
offset = rtw_wnm_btm_candidates_offset_get(pframe);
7043
if ((offset == 0) || ((frame_len - offset) <= 15))
7044
return;
7045
7046
ptr = (pframe + offset);
7047
elem_len = (frame_len - offset);
7048
rtw_wnm_btm_candidates_survey(padapter, ptr, elem_len, _TRUE);
7049
reason = rtw_wmn_btm_rsp_reason_decision(padapter, &pframe[3]);
7050
rtw_wnm_issue_action(padapter,
7051
RTW_WLAN_ACTION_WNM_BTM_RSP, reason);
7052
7053
if (reason == 0)
7054
rtw_wnm_roam_scan(padapter);
7055
}
7056
7057
void rtw_wnm_reset_btm_candidate(struct roam_nb_info *pnb)
7058
{
7059
pnb->preference_en = _FALSE;
7060
_rtw_memset(pnb->roam_target_addr, 0, ETH_ALEN);
7061
}
7062
7063
void rtw_wnm_reset_btm_state(_adapter *padapter)
7064
{
7065
struct roam_nb_info *pnb = &(padapter->mlmepriv.nb_info);
7066
7067
pnb->last_nb_rpt_entries = 0;
7068
pnb->nb_rpt_is_same = _TRUE;
7069
pnb->nb_rpt_valid = _FALSE;
7070
pnb->nb_rpt_ch_list_num = 0;
7071
rtw_wnm_reset_btm_candidate(pnb);
7072
_rtw_memset(&pnb->nb_rpt, 0, sizeof(pnb->nb_rpt));
7073
_rtw_memset(&pnb->nb_rpt_ch_list, 0, sizeof(pnb->nb_rpt_ch_list));
7074
}
7075
7076
void rtw_wnm_issue_action(_adapter *padapter, u8 action, u8 reason)
7077
{
7078
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7079
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7080
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7081
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7082
struct xmit_frame *pmgntframe;
7083
struct rtw_ieee80211_hdr *pwlanhdr;
7084
struct pkt_attrib *pattrib;
7085
u8 category, dialog_token, termination_delay, *pframe;
7086
u16 *fctrl;
7087
7088
if ((pmgntframe = alloc_mgtxmitframe(pxmitpriv)) == NULL)
7089
return ;
7090
7091
pattrib = &(pmgntframe->attrib);
7092
update_mgntframe_attrib(padapter, pattrib);
7093
_rtw_memset(pmgntframe->buf_addr, 0, (WLANHDR_OFFSET + TXDESC_OFFSET));
7094
7095
pframe = (u8 *)(pmgntframe->buf_addr + TXDESC_OFFSET);
7096
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7097
7098
fctrl = &(pwlanhdr->frame_ctl);
7099
*(fctrl) = 0;
7100
7101
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7102
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7103
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
7104
7105
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
7106
pmlmeext->mgnt_seq++;
7107
set_frame_sub_type(pframe, WIFI_ACTION);
7108
7109
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7110
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7111
7112
category = RTW_WLAN_CATEGORY_WNM;
7113
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
7114
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
7115
7116
switch (action) {
7117
case RTW_WLAN_ACTION_WNM_BTM_QUERY:
7118
pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen));
7119
pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen));
7120
RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_QUERY sent.\n");
7121
break;
7122
case RTW_WLAN_ACTION_WNM_BTM_RSP:
7123
termination_delay = 0;
7124
pframe = rtw_set_fixed_ie(pframe, 1, &(dialog_token), &(pattrib->pktlen));
7125
pframe = rtw_set_fixed_ie(pframe, 1, &(reason), &(pattrib->pktlen));
7126
pframe = rtw_set_fixed_ie(pframe, 1, &(termination_delay), &(pattrib->pktlen));
7127
if (!is_zero_mac_addr(pmlmepriv->nb_info.roam_target_addr)) {
7128
pframe = rtw_set_fixed_ie(pframe, 6,
7129
pmlmepriv->nb_info.roam_target_addr, &(pattrib->pktlen));
7130
}
7131
RTW_INFO("WNM: RTW_WLAN_ACTION_WNM_BTM_RSP sent. reason = %d\n", reason);
7132
break;
7133
default:
7134
goto exit;
7135
}
7136
7137
pattrib->last_txcmdsz = pattrib->pktlen;
7138
dump_mgntframe(padapter, pmgntframe);
7139
7140
exit:
7141
return;
7142
}
7143
#endif
7144
7145
unsigned int OnAction_ht(_adapter *padapter, union recv_frame *precv_frame)
7146
{
7147
u8 *pframe = precv_frame->u.hdr.rx_data;
7148
u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7149
u8 category, action;
7150
7151
/* check RA matches or not */
7152
if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7153
goto exit;
7154
7155
category = frame_body[0];
7156
if (category != RTW_WLAN_CATEGORY_HT)
7157
goto exit;
7158
7159
action = frame_body[1];
7160
switch (action) {
7161
case RTW_WLAN_ACTION_HT_SM_PS:
7162
#ifdef CONFIG_80211N_HT
7163
#ifdef CONFIG_AP_MODE
7164
if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
7165
rtw_process_ht_action_smps(padapter, get_addr2_ptr(pframe), frame_body[2]);
7166
#endif /*CONFIG_AP_MODE*/
7167
#endif /*CONFIG_80211N_HT*/
7168
break;
7169
case RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING:
7170
#ifdef CONFIG_BEAMFORMING
7171
/*RTW_INFO("RTW_WLAN_ACTION_HT_COMPRESS_BEAMFORMING\n");*/
7172
rtw_beamforming_get_report_frame(padapter, precv_frame);
7173
#endif /*CONFIG_BEAMFORMING*/
7174
break;
7175
default:
7176
break;
7177
}
7178
7179
exit:
7180
7181
return _SUCCESS;
7182
}
7183
7184
#ifdef CONFIG_IEEE80211W
7185
unsigned int OnAction_sa_query(_adapter *padapter, union recv_frame *precv_frame)
7186
{
7187
u8 *pframe = precv_frame->u.hdr.rx_data;
7188
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
7189
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7190
struct sta_info *psta;
7191
struct sta_priv *pstapriv = &padapter->stapriv;
7192
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7193
u16 tid;
7194
/* Baron */
7195
7196
RTW_INFO("OnAction_sa_query\n");
7197
7198
switch (pframe[WLAN_HDR_A3_LEN + 1]) {
7199
case 0: /* SA Query req */
7200
_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7201
RTW_INFO("OnAction_sa_query request,action=%d, tid=%04x, pframe=%02x-%02x\n"
7202
, pframe[WLAN_HDR_A3_LEN + 1], tid, pframe[WLAN_HDR_A3_LEN + 2], pframe[WLAN_HDR_A3_LEN + 3]);
7203
issue_action_SA_Query(padapter, get_addr2_ptr(pframe), 1, tid, IEEE80211W_RIGHT_KEY);
7204
break;
7205
7206
case 1: /* SA Query rsp */
7207
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
7208
if (psta != NULL)
7209
_cancel_timer_ex(&psta->dot11w_expire_timer);
7210
7211
_rtw_memcpy(&tid, &pframe[WLAN_HDR_A3_LEN + 2], sizeof(u16));
7212
RTW_INFO("OnAction_sa_query response,action=%d, tid=%04x, cancel timer\n", pframe[WLAN_HDR_A3_LEN + 1], tid);
7213
break;
7214
default:
7215
break;
7216
}
7217
if (0) {
7218
int pp;
7219
printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
7220
for (pp = 0; pp < pattrib->pkt_len; pp++)
7221
printk(" %02x ", pframe[pp]);
7222
printk("\n");
7223
}
7224
7225
return _SUCCESS;
7226
}
7227
#endif /* CONFIG_IEEE80211W */
7228
7229
unsigned int on_action_rm(_adapter *padapter, union recv_frame *precv_frame)
7230
{
7231
#ifdef CONFIG_RTW_80211K
7232
return rm_on_action(padapter, precv_frame);
7233
#else
7234
return _SUCCESS;
7235
#endif /* CONFIG_RTW_80211K */
7236
}
7237
7238
unsigned int OnAction_wmm(_adapter *padapter, union recv_frame *precv_frame)
7239
{
7240
return _SUCCESS;
7241
}
7242
7243
unsigned int OnAction_vht(_adapter *padapter, union recv_frame *precv_frame)
7244
{
7245
#ifdef CONFIG_80211AC_VHT
7246
u8 *pframe = precv_frame->u.hdr.rx_data;
7247
struct rtw_ieee80211_hdr_3addr *whdr = (struct rtw_ieee80211_hdr_3addr *)pframe;
7248
u8 *frame_body = pframe + sizeof(struct rtw_ieee80211_hdr_3addr);
7249
u8 category, action;
7250
struct sta_info *psta = NULL;
7251
7252
/* check RA matches or not */
7253
if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7254
goto exit;
7255
7256
category = frame_body[0];
7257
if (category != RTW_WLAN_CATEGORY_VHT)
7258
goto exit;
7259
7260
action = frame_body[1];
7261
switch (action) {
7262
case RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING:
7263
#ifdef CONFIG_BEAMFORMING
7264
/*RTW_INFO("RTW_WLAN_ACTION_VHT_COMPRESSED_BEAMFORMING\n");*/
7265
rtw_beamforming_get_report_frame(padapter, precv_frame);
7266
#endif /*CONFIG_BEAMFORMING*/
7267
break;
7268
case RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION:
7269
/* CategoryCode(1) + ActionCode(1) + OpModeNotification(1) */
7270
/* RTW_INFO("RTW_WLAN_ACTION_VHT_OPMODE_NOTIFICATION\n"); */
7271
psta = rtw_get_stainfo(&padapter->stapriv, whdr->addr2);
7272
if (psta)
7273
rtw_process_vht_op_mode_notify(padapter, &frame_body[2], psta);
7274
break;
7275
case RTW_WLAN_ACTION_VHT_GROUPID_MANAGEMENT:
7276
#ifdef CONFIG_BEAMFORMING
7277
#ifdef RTW_BEAMFORMING_VERSION_2
7278
rtw_beamforming_get_vht_gid_mgnt_frame(padapter, precv_frame);
7279
#endif /* RTW_BEAMFORMING_VERSION_2 */
7280
#endif /* CONFIG_BEAMFORMING */
7281
break;
7282
default:
7283
break;
7284
}
7285
7286
exit:
7287
#endif /* CONFIG_80211AC_VHT */
7288
7289
return _SUCCESS;
7290
}
7291
7292
unsigned int OnAction_p2p(_adapter *padapter, union recv_frame *precv_frame)
7293
{
7294
#ifdef CONFIG_P2P
7295
u8 *frame_body;
7296
u8 category, OUI_Subtype, dialogToken = 0;
7297
u8 *pframe = precv_frame->u.hdr.rx_data;
7298
uint len = precv_frame->u.hdr.len;
7299
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7300
7301
/* check RA matches or not */
7302
if (!_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(pframe), ETH_ALEN))
7303
return _SUCCESS;
7304
7305
frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7306
7307
category = frame_body[0];
7308
if (category != RTW_WLAN_CATEGORY_P2P)
7309
return _SUCCESS;
7310
7311
if (cpu_to_be32(*((u32 *)(frame_body + 1))) != P2POUI)
7312
return _SUCCESS;
7313
7314
#ifdef CONFIG_IOCTL_CFG80211
7315
if (adapter_wdev_data(padapter)->p2p_enabled
7316
&& pwdinfo->driver_interface == DRIVER_CFG80211
7317
) {
7318
rtw_cfg80211_rx_action_p2p(padapter, precv_frame);
7319
return _SUCCESS;
7320
} else
7321
#endif /* CONFIG_IOCTL_CFG80211 */
7322
{
7323
len -= sizeof(struct rtw_ieee80211_hdr_3addr);
7324
OUI_Subtype = frame_body[5];
7325
dialogToken = frame_body[6];
7326
7327
switch (OUI_Subtype) {
7328
case P2P_NOTICE_OF_ABSENCE:
7329
7330
break;
7331
7332
case P2P_PRESENCE_REQUEST:
7333
7334
process_p2p_presence_req(pwdinfo, pframe, len);
7335
7336
break;
7337
7338
case P2P_PRESENCE_RESPONSE:
7339
7340
break;
7341
7342
case P2P_GO_DISC_REQUEST:
7343
7344
break;
7345
7346
default:
7347
break;
7348
7349
}
7350
}
7351
#endif /* CONFIG_P2P */
7352
7353
return _SUCCESS;
7354
7355
}
7356
7357
unsigned int OnAction(_adapter *padapter, union recv_frame *precv_frame)
7358
{
7359
int i;
7360
unsigned char category;
7361
struct action_handler *ptable;
7362
unsigned char *frame_body;
7363
u8 *pframe = precv_frame->u.hdr.rx_data;
7364
7365
frame_body = (unsigned char *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
7366
7367
category = frame_body[0];
7368
7369
for (i = 0; i < sizeof(OnAction_tbl) / sizeof(struct action_handler); i++) {
7370
ptable = &OnAction_tbl[i];
7371
7372
if (category == ptable->num)
7373
ptable->func(padapter, precv_frame);
7374
7375
}
7376
7377
return _SUCCESS;
7378
7379
}
7380
7381
unsigned int DoReserved(_adapter *padapter, union recv_frame *precv_frame)
7382
{
7383
7384
/* RTW_INFO("rcvd mgt frame(%x, %x)\n", (get_frame_sub_type(pframe) >> 4), *(unsigned int *)GetAddr1Ptr(pframe)); */
7385
return _SUCCESS;
7386
}
7387
7388
struct xmit_frame *_alloc_mgtxmitframe(struct xmit_priv *pxmitpriv, bool once)
7389
{
7390
struct xmit_frame *pmgntframe;
7391
struct xmit_buf *pxmitbuf;
7392
7393
if (once)
7394
pmgntframe = rtw_alloc_xmitframe_once(pxmitpriv);
7395
else
7396
pmgntframe = rtw_alloc_xmitframe_ext(pxmitpriv);
7397
7398
if (pmgntframe == NULL) {
7399
RTW_INFO(FUNC_ADPT_FMT" alloc xmitframe fail, once:%d\n", FUNC_ADPT_ARG(pxmitpriv->adapter), once);
7400
goto exit;
7401
}
7402
7403
pxmitbuf = rtw_alloc_xmitbuf_ext(pxmitpriv);
7404
if (pxmitbuf == NULL) {
7405
RTW_INFO(FUNC_ADPT_FMT" alloc xmitbuf fail\n", FUNC_ADPT_ARG(pxmitpriv->adapter));
7406
rtw_free_xmitframe(pxmitpriv, pmgntframe);
7407
pmgntframe = NULL;
7408
goto exit;
7409
}
7410
7411
pmgntframe->frame_tag = MGNT_FRAMETAG;
7412
pmgntframe->pxmitbuf = pxmitbuf;
7413
pmgntframe->buf_addr = pxmitbuf->pbuf;
7414
pxmitbuf->priv_data = pmgntframe;
7415
7416
exit:
7417
return pmgntframe;
7418
7419
}
7420
7421
inline struct xmit_frame *alloc_mgtxmitframe(struct xmit_priv *pxmitpriv)
7422
{
7423
return _alloc_mgtxmitframe(pxmitpriv, _FALSE);
7424
}
7425
7426
inline struct xmit_frame *alloc_mgtxmitframe_once(struct xmit_priv *pxmitpriv)
7427
{
7428
return _alloc_mgtxmitframe(pxmitpriv, _TRUE);
7429
}
7430
7431
7432
/****************************************************************************
7433
7434
Following are some TX fuctions for WiFi MLME
7435
7436
*****************************************************************************/
7437
7438
void update_mgnt_tx_rate(_adapter *padapter, u8 rate)
7439
{
7440
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7441
7442
pmlmeext->tx_rate = rate;
7443
/* RTW_INFO("%s(): rate = %x\n",__FUNCTION__, rate); */
7444
}
7445
7446
7447
void update_monitor_frame_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7448
{
7449
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
7450
u8 wireless_mode;
7451
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7452
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7453
struct sta_info *psta = NULL;
7454
struct sta_priv *pstapriv = &padapter->stapriv;
7455
7456
psta = rtw_get_stainfo(pstapriv, pattrib->ra);
7457
7458
pattrib->hdrlen = 24;
7459
pattrib->nr_frags = 1;
7460
pattrib->priority = 7;
7461
pattrib->mac_id = RTW_DEFAULT_MGMT_MACID;
7462
pattrib->qsel = QSLT_MGNT;
7463
7464
pattrib->pktlen = 0;
7465
7466
if (pmlmeext->tx_rate == IEEE80211_CCK_RATE_1MB)
7467
wireless_mode = WIRELESS_11B;
7468
else
7469
wireless_mode = WIRELESS_11G;
7470
7471
pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7472
#ifdef CONFIG_80211AC_VHT
7473
if (pHalData->rf_type == RF_1T1R)
7474
pattrib->raid = RATEID_IDX_VHT_1SS;
7475
else if (pHalData->rf_type == RF_2T2R || pHalData->rf_type == RF_2T4R)
7476
pattrib->raid = RATEID_IDX_VHT_2SS;
7477
else if (pHalData->rf_type == RF_3T3R)
7478
pattrib->raid = RATEID_IDX_VHT_3SS;
7479
else
7480
pattrib->raid = RATEID_IDX_BGN_40M_1SS;
7481
#endif
7482
7483
#ifdef CONFIG_80211AC_VHT
7484
pattrib->rate = MGN_VHT1SS_MCS9;
7485
#else
7486
pattrib->rate = MGN_MCS7;
7487
#endif
7488
7489
pattrib->encrypt = _NO_PRIVACY_;
7490
pattrib->bswenc = _FALSE;
7491
7492
pattrib->qos_en = _FALSE;
7493
pattrib->ht_en = 1;
7494
pattrib->bwmode = CHANNEL_WIDTH_20;
7495
pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7496
pattrib->sgi = _FALSE;
7497
7498
pattrib->seqnum = pmlmeext->mgnt_seq;
7499
7500
pattrib->retry_ctrl = _TRUE;
7501
7502
pattrib->mbssid = 0;
7503
pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7504
7505
}
7506
7507
7508
void update_mgntframe_attrib(_adapter *padapter, struct pkt_attrib *pattrib)
7509
{
7510
u8 wireless_mode;
7511
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7512
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7513
7514
#ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
7515
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7516
#endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
7517
7518
/* _rtw_memset((u8 *)(pattrib), 0, sizeof(struct pkt_attrib)); */
7519
7520
pattrib->hdrlen = 24;
7521
pattrib->nr_frags = 1;
7522
pattrib->priority = 7;
7523
pattrib->mac_id = RTW_DEFAULT_MGMT_MACID;
7524
pattrib->qsel = QSLT_MGNT;
7525
7526
#ifdef CONFIG_MCC_MODE
7527
update_mcc_mgntframe_attrib(padapter, pattrib);
7528
#endif
7529
7530
7531
#ifdef CONFIG_P2P_PS_NOA_USE_MACID_SLEEP
7532
#ifdef CONFIG_CONCURRENT_MODE
7533
if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
7534
#endif /* CONFIG_CONCURRENT_MODE */
7535
if (MLME_IS_GC(padapter)) {
7536
if (pwdinfo->p2p_ps_mode > P2P_PS_NONE) {
7537
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
7538
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7539
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7540
struct sta_priv *pstapriv = &padapter->stapriv;
7541
struct sta_info *psta;
7542
7543
psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
7544
if (psta) {
7545
/* use macid sleep during NoA, mgmt frame use ac queue & ap macid */
7546
pattrib->mac_id = psta->cmn.mac_id;
7547
pattrib->qsel = QSLT_VO;
7548
} else {
7549
if (pwdinfo->p2p_ps_state != P2P_PS_DISABLE)
7550
RTW_ERR("%s , psta was NULL\n", __func__);
7551
}
7552
}
7553
}
7554
#endif /* CONFIG_P2P_PS_NOA_USE_MACID_SLEEP */
7555
7556
7557
pattrib->pktlen = 0;
7558
7559
if (IS_CCK_RATE(pmlmeext->tx_rate))
7560
wireless_mode = WIRELESS_11B;
7561
else
7562
wireless_mode = WIRELESS_11G;
7563
pattrib->raid = rtw_get_mgntframe_raid(padapter, wireless_mode);
7564
pattrib->rate = pmlmeext->tx_rate;
7565
7566
pattrib->encrypt = _NO_PRIVACY_;
7567
pattrib->bswenc = _FALSE;
7568
7569
pattrib->qos_en = _FALSE;
7570
pattrib->ht_en = _FALSE;
7571
pattrib->bwmode = CHANNEL_WIDTH_20;
7572
pattrib->ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
7573
pattrib->sgi = _FALSE;
7574
7575
pattrib->seqnum = pmlmeext->mgnt_seq;
7576
7577
pattrib->retry_ctrl = _TRUE;
7578
7579
pattrib->mbssid = 0;
7580
pattrib->hw_ssn_sel = pxmitpriv->hw_ssn_seq_no;
7581
}
7582
7583
void update_mgntframe_attrib_addr(_adapter *padapter, struct xmit_frame *pmgntframe)
7584
{
7585
u8 *pframe;
7586
struct pkt_attrib *pattrib = &pmgntframe->attrib;
7587
#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY)
7588
struct sta_info *sta = NULL;
7589
#endif
7590
7591
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7592
7593
_rtw_memcpy(pattrib->ra, GetAddr1Ptr(pframe), ETH_ALEN);
7594
_rtw_memcpy(pattrib->ta, get_addr2_ptr(pframe), ETH_ALEN);
7595
7596
#if defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY)
7597
sta = pattrib->psta;
7598
if (!sta) {
7599
sta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
7600
pattrib->psta = sta;
7601
}
7602
#ifdef CONFIG_BEAMFORMING
7603
if (sta)
7604
update_attrib_txbf_info(padapter, pattrib, sta);
7605
#endif
7606
#endif /* defined(CONFIG_BEAMFORMING) || defined(CONFIG_ANTENNA_DIVERSITY) */
7607
}
7608
7609
void dump_mgntframe(_adapter *padapter, struct xmit_frame *pmgntframe)
7610
{
7611
if (RTW_CANNOT_RUN(padapter)) {
7612
rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7613
rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7614
return;
7615
}
7616
7617
rtw_hal_mgnt_xmit(padapter, pmgntframe);
7618
}
7619
7620
s32 dump_mgntframe_and_wait(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7621
{
7622
s32 ret = _FAIL;
7623
_irqL irqL;
7624
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
7625
struct xmit_buf *pxmitbuf = pmgntframe->pxmitbuf;
7626
struct submit_ctx sctx;
7627
7628
if (RTW_CANNOT_RUN(padapter)) {
7629
rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7630
rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7631
return ret;
7632
}
7633
7634
rtw_sctx_init(&sctx, timeout_ms);
7635
pxmitbuf->sctx = &sctx;
7636
7637
ret = rtw_hal_mgnt_xmit(padapter, pmgntframe);
7638
7639
if (ret == _SUCCESS)
7640
ret = rtw_sctx_wait(&sctx, __func__);
7641
7642
_enter_critical(&pxmitpriv->lock_sctx, &irqL);
7643
pxmitbuf->sctx = NULL;
7644
_exit_critical(&pxmitpriv->lock_sctx, &irqL);
7645
7646
return ret;
7647
}
7648
7649
s32 dump_mgntframe_and_wait_ack_timeout(_adapter *padapter, struct xmit_frame *pmgntframe, int timeout_ms)
7650
{
7651
#ifdef CONFIG_XMIT_ACK
7652
static u8 seq_no = 0;
7653
s32 ret = _FAIL;
7654
struct xmit_priv *pxmitpriv = &(GET_PRIMARY_ADAPTER(padapter))->xmitpriv;
7655
7656
if (RTW_CANNOT_RUN(padapter)) {
7657
rtw_free_xmitbuf(&padapter->xmitpriv, pmgntframe->pxmitbuf);
7658
rtw_free_xmitframe(&padapter->xmitpriv, pmgntframe);
7659
return -1;
7660
}
7661
7662
_enter_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7663
pxmitpriv->ack_tx = _TRUE;
7664
pxmitpriv->seq_no = seq_no++;
7665
pmgntframe->ack_report = 1;
7666
rtw_sctx_init(&(pxmitpriv->ack_tx_ops), timeout_ms);
7667
if (rtw_hal_mgnt_xmit(padapter, pmgntframe) == _SUCCESS)
7668
ret = rtw_sctx_wait(&(pxmitpriv->ack_tx_ops), __func__);
7669
7670
pxmitpriv->ack_tx = _FALSE;
7671
_exit_critical_mutex(&pxmitpriv->ack_tx_mutex, NULL);
7672
7673
return ret;
7674
#else /* !CONFIG_XMIT_ACK */
7675
dump_mgntframe(padapter, pmgntframe);
7676
rtw_msleep_os(50);
7677
return _SUCCESS;
7678
#endif /* !CONFIG_XMIT_ACK */
7679
}
7680
7681
s32 dump_mgntframe_and_wait_ack(_adapter *padapter, struct xmit_frame *pmgntframe)
7682
{
7683
/* In this case, use 500 ms as the default wait_ack timeout */
7684
return dump_mgntframe_and_wait_ack_timeout(padapter, pmgntframe, 500);
7685
}
7686
7687
7688
int update_hidden_ssid(u8 *ies, u32 ies_len, u8 hidden_ssid_mode)
7689
{
7690
u8 *ssid_ie;
7691
sint ssid_len_ori;
7692
int len_diff = 0;
7693
7694
ssid_ie = rtw_get_ie(ies, WLAN_EID_SSID, &ssid_len_ori, ies_len);
7695
7696
/* RTW_INFO("%s hidden_ssid_mode:%u, ssid_ie:%p, ssid_len_ori:%d\n", __FUNCTION__, hidden_ssid_mode, ssid_ie, ssid_len_ori); */
7697
7698
if (ssid_ie && ssid_len_ori > 0) {
7699
switch (hidden_ssid_mode) {
7700
case 1: {
7701
u8 *next_ie = ssid_ie + 2 + ssid_len_ori;
7702
u32 remain_len = 0;
7703
7704
remain_len = ies_len - (next_ie - ies);
7705
7706
ssid_ie[1] = 0;
7707
_rtw_memcpy(ssid_ie + 2, next_ie, remain_len);
7708
len_diff -= ssid_len_ori;
7709
7710
break;
7711
}
7712
case 2:
7713
_rtw_memset(&ssid_ie[2], 0, ssid_len_ori);
7714
break;
7715
default:
7716
break;
7717
}
7718
}
7719
7720
return len_diff;
7721
}
7722
7723
void issue_beacon(_adapter *padapter, int timeout_ms)
7724
{
7725
struct xmit_frame *pmgntframe;
7726
struct pkt_attrib *pattrib;
7727
unsigned char *pframe;
7728
struct rtw_ieee80211_hdr *pwlanhdr;
7729
unsigned short *fctrl;
7730
unsigned int rate_len;
7731
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
7732
#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7733
_irqL irqL;
7734
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
7735
#endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
7736
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
7737
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
7738
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
7739
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
7740
#ifdef CONFIG_P2P
7741
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
7742
#endif /* CONFIG_P2P */
7743
7744
7745
/* RTW_INFO("%s\n", __FUNCTION__); */
7746
7747
#ifdef CONFIG_BCN_ICF
7748
pmgntframe = rtw_alloc_bcnxmitframe(pxmitpriv);
7749
if (pmgntframe == NULL)
7750
#else
7751
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
7752
if (pmgntframe == NULL)
7753
#endif
7754
{
7755
RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
7756
return;
7757
}
7758
#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
7759
_enter_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
7760
#endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
7761
7762
/* update attribute */
7763
pattrib = &pmgntframe->attrib;
7764
update_mgntframe_attrib(padapter, pattrib);
7765
pattrib->qsel = QSLT_BEACON;
7766
7767
#if defined(CONFIG_CONCURRENT_MODE) && (!defined(CONFIG_SWTIMER_BASED_TXBCN))
7768
if (padapter->hw_port == HW_PORT1)
7769
pattrib->mbssid = 1;
7770
#endif
7771
#ifdef CONFIG_FW_HANDLE_TXBCN
7772
if (padapter->vap_id != CONFIG_LIMITED_AP_NUM)
7773
pattrib->mbssid = padapter->vap_id;
7774
#endif
7775
7776
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
7777
7778
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
7779
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
7780
7781
7782
fctrl = &(pwlanhdr->frame_ctl);
7783
*(fctrl) = 0;
7784
7785
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
7786
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
7787
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(cur_network), ETH_ALEN);
7788
7789
SetSeqNum(pwlanhdr, 0/*pmlmeext->mgnt_seq*/);
7790
/* pmlmeext->mgnt_seq++; */
7791
set_frame_sub_type(pframe, WIFI_BEACON);
7792
7793
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
7794
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
7795
7796
if (MLME_IS_AP(padapter) || MLME_IS_MESH(padapter)) {
7797
/* RTW_INFO("ie len=%d\n", cur_network->IELength); */
7798
#ifdef CONFIG_P2P
7799
/* for P2P : Primary Device Type & Device Name */
7800
u32 wpsielen = 0, insert_len = 0;
7801
u8 *wpsie = NULL;
7802
wpsie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wpsielen);
7803
7804
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && wpsie && wpsielen > 0) {
7805
uint wps_offset, remainder_ielen;
7806
u8 *premainder_ie, *pframe_wscie;
7807
7808
wps_offset = (uint)(wpsie - cur_network->IEs);
7809
7810
premainder_ie = wpsie + wpsielen;
7811
7812
remainder_ielen = cur_network->IELength - wps_offset - wpsielen;
7813
7814
#ifdef CONFIG_IOCTL_CFG80211
7815
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
7816
if (pmlmepriv->wps_beacon_ie && pmlmepriv->wps_beacon_ie_len > 0) {
7817
_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
7818
pframe += wps_offset;
7819
pattrib->pktlen += wps_offset;
7820
7821
_rtw_memcpy(pframe, pmlmepriv->wps_beacon_ie, pmlmepriv->wps_beacon_ie_len);
7822
pframe += pmlmepriv->wps_beacon_ie_len;
7823
pattrib->pktlen += pmlmepriv->wps_beacon_ie_len;
7824
7825
/* copy remainder_ie to pframe */
7826
_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7827
pframe += remainder_ielen;
7828
pattrib->pktlen += remainder_ielen;
7829
} else {
7830
_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7831
pframe += cur_network->IELength;
7832
pattrib->pktlen += cur_network->IELength;
7833
}
7834
} else
7835
#endif /* CONFIG_IOCTL_CFG80211 */
7836
{
7837
pframe_wscie = pframe + wps_offset;
7838
_rtw_memcpy(pframe, cur_network->IEs, wps_offset + wpsielen);
7839
pframe += (wps_offset + wpsielen);
7840
pattrib->pktlen += (wps_offset + wpsielen);
7841
7842
/* now pframe is end of wsc ie, insert Primary Device Type & Device Name */
7843
/* Primary Device Type */
7844
/* Type: */
7845
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_PRIMARY_DEV_TYPE);
7846
insert_len += 2;
7847
7848
/* Length: */
7849
*(u16 *)(pframe + insert_len) = cpu_to_be16(0x0008);
7850
insert_len += 2;
7851
7852
/* Value: */
7853
/* Category ID */
7854
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
7855
insert_len += 2;
7856
7857
/* OUI */
7858
*(u32 *)(pframe + insert_len) = cpu_to_be32(WPSOUI);
7859
insert_len += 4;
7860
7861
/* Sub Category ID */
7862
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
7863
insert_len += 2;
7864
7865
7866
/* Device Name */
7867
/* Type: */
7868
*(u16 *)(pframe + insert_len) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
7869
insert_len += 2;
7870
7871
/* Length: */
7872
*(u16 *)(pframe + insert_len) = cpu_to_be16(pwdinfo->device_name_len);
7873
insert_len += 2;
7874
7875
/* Value: */
7876
_rtw_memcpy(pframe + insert_len, pwdinfo->device_name, pwdinfo->device_name_len);
7877
insert_len += pwdinfo->device_name_len;
7878
7879
7880
/* update wsc ie length */
7881
*(pframe_wscie + 1) = (wpsielen - 2) + insert_len;
7882
7883
/* pframe move to end */
7884
pframe += insert_len;
7885
pattrib->pktlen += insert_len;
7886
7887
/* copy remainder_ie to pframe */
7888
_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
7889
pframe += remainder_ielen;
7890
pattrib->pktlen += remainder_ielen;
7891
}
7892
} else
7893
#endif /* CONFIG_P2P */
7894
{
7895
int len_diff;
7896
_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
7897
len_diff = update_hidden_ssid(
7898
pframe + _BEACON_IE_OFFSET_
7899
, cur_network->IELength - _BEACON_IE_OFFSET_
7900
, pmlmeinfo->hidden_ssid_mode
7901
);
7902
pframe += (cur_network->IELength + len_diff);
7903
pattrib->pktlen += (cur_network->IELength + len_diff);
7904
}
7905
7906
{
7907
u8 *wps_ie;
7908
uint wps_ielen;
7909
u8 sr = 0;
7910
wps_ie = rtw_get_wps_ie(pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr) + _BEACON_IE_OFFSET_,
7911
pattrib->pktlen - sizeof(struct rtw_ieee80211_hdr_3addr) - _BEACON_IE_OFFSET_, NULL, &wps_ielen);
7912
if (wps_ie && wps_ielen > 0)
7913
rtw_get_wps_attr_content(wps_ie, wps_ielen, WPS_ATTR_SELECTED_REGISTRAR, (u8 *)(&sr), NULL);
7914
if (sr != 0)
7915
set_fwstate(pmlmepriv, WIFI_UNDER_WPS);
7916
else
7917
_clr_fwstate_(pmlmepriv, WIFI_UNDER_WPS);
7918
}
7919
7920
#ifdef CONFIG_RTW_80211K
7921
pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_,
7922
sizeof(padapter->rmpriv.rm_en_cap_def),
7923
padapter->rmpriv.rm_en_cap_def, &pattrib->pktlen);
7924
#endif
7925
7926
#ifdef CONFIG_P2P
7927
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
7928
u32 len;
7929
#ifdef CONFIG_IOCTL_CFG80211
7930
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
7931
len = pmlmepriv->p2p_beacon_ie_len;
7932
if (pmlmepriv->p2p_beacon_ie && len > 0)
7933
_rtw_memcpy(pframe, pmlmepriv->p2p_beacon_ie, len);
7934
} else
7935
#endif /* CONFIG_IOCTL_CFG80211 */
7936
{
7937
len = build_beacon_p2p_ie(pwdinfo, pframe);
7938
}
7939
7940
pframe += len;
7941
pattrib->pktlen += len;
7942
7943
#ifdef CONFIG_MCC_MODE
7944
pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
7945
#endif /* CONFIG_MCC_MODE*/
7946
7947
#ifdef CONFIG_WFD
7948
len = rtw_append_beacon_wfd_ie(padapter, pframe);
7949
pframe += len;
7950
pattrib->pktlen += len;
7951
#endif
7952
}
7953
#endif /* CONFIG_P2P */
7954
#ifdef CONFIG_RTW_REPEATER_SON
7955
rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
7956
#endif
7957
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
7958
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_BEACON_VENDOR_IE_BIT);
7959
#endif
7960
7961
#ifdef CONFIG_RTL8812A
7962
pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
7963
#endif/*CONFIG_RTL8812A*/
7964
7965
goto _issue_bcn;
7966
7967
}
7968
7969
/* below for ad-hoc mode */
7970
7971
/* timestamp will be inserted by hardware */
7972
pframe += 8;
7973
pattrib->pktlen += 8;
7974
7975
/* beacon interval: 2 bytes */
7976
7977
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
7978
7979
pframe += 2;
7980
pattrib->pktlen += 2;
7981
7982
/* capability info: 2 bytes */
7983
7984
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
7985
7986
pframe += 2;
7987
pattrib->pktlen += 2;
7988
7989
/* SSID */
7990
pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
7991
7992
/* supported rates... */
7993
rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
7994
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
7995
7996
/* DS parameter set */
7997
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
7998
7999
/* if( (pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) */
8000
{
8001
u8 erpinfo = 0;
8002
u32 ATIMWindow;
8003
/* IBSS Parameter Set... */
8004
/* ATIMWindow = cur->Configuration.ATIMWindow; */
8005
ATIMWindow = 0;
8006
pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8007
8008
/* ERP IE */
8009
pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8010
}
8011
8012
8013
/* EXTERNDED SUPPORTED RATE */
8014
if (rate_len > 8)
8015
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8016
8017
8018
/* todo:HT for adhoc */
8019
8020
_issue_bcn:
8021
8022
#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8023
pmlmepriv->update_bcn = _FALSE;
8024
8025
_exit_critical_bh(&pmlmepriv->bcn_update_lock, &irqL);
8026
#endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8027
8028
if ((pattrib->pktlen + TXDESC_SIZE) > MAX_BEACON_LEN) {
8029
RTW_ERR("beacon frame too large ,len(%d,%d)\n",
8030
(pattrib->pktlen + TXDESC_SIZE), MAX_BEACON_LEN);
8031
rtw_warn_on(1);
8032
return;
8033
}
8034
8035
pattrib->last_txcmdsz = pattrib->pktlen;
8036
8037
/* RTW_INFO("issue bcn_sz=%d\n", pattrib->last_txcmdsz); */
8038
if (timeout_ms > 0)
8039
dump_mgntframe_and_wait(padapter, pmgntframe, timeout_ms);
8040
else
8041
dump_mgntframe(padapter, pmgntframe);
8042
8043
}
8044
8045
void issue_probersp(_adapter *padapter, unsigned char *da, u8 is_valid_p2p_probereq)
8046
{
8047
struct xmit_frame *pmgntframe;
8048
struct pkt_attrib *pattrib;
8049
unsigned char *pframe;
8050
struct rtw_ieee80211_hdr *pwlanhdr;
8051
unsigned short *fctrl;
8052
unsigned char *mac, *bssid;
8053
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8054
#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8055
u8 *pwps_ie;
8056
uint wps_ielen;
8057
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
8058
#endif /* #if defined (CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME) */
8059
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8060
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8061
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
8062
unsigned int rate_len;
8063
#ifdef CONFIG_P2P
8064
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8065
#endif /* CONFIG_P2P */
8066
8067
/* RTW_INFO("%s\n", __FUNCTION__); */
8068
8069
if (da == NULL)
8070
return;
8071
8072
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8073
return;
8074
8075
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8076
if (pmgntframe == NULL) {
8077
RTW_INFO("%s, alloc mgnt frame fail\n", __FUNCTION__);
8078
return;
8079
}
8080
8081
8082
/* update attribute */
8083
pattrib = &pmgntframe->attrib;
8084
update_mgntframe_attrib(padapter, pattrib);
8085
8086
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8087
8088
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8089
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8090
8091
mac = adapter_mac_addr(padapter);
8092
bssid = cur_network->MacAddress;
8093
8094
fctrl = &(pwlanhdr->frame_ctl);
8095
*(fctrl) = 0;
8096
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8097
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8098
_rtw_memcpy(pwlanhdr->addr3, bssid, ETH_ALEN);
8099
8100
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8101
pmlmeext->mgnt_seq++;
8102
set_frame_sub_type(fctrl, WIFI_PROBERSP);
8103
8104
pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8105
pattrib->pktlen = pattrib->hdrlen;
8106
pframe += pattrib->hdrlen;
8107
8108
8109
if (cur_network->IELength > MAX_IE_SZ)
8110
return;
8111
8112
#if defined(CONFIG_AP_MODE) && defined (CONFIG_NATIVEAP_MLME)
8113
if ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
8114
pwps_ie = rtw_get_wps_ie(cur_network->IEs + _FIXED_IE_LENGTH_, cur_network->IELength - _FIXED_IE_LENGTH_, NULL, &wps_ielen);
8115
8116
/* inerset & update wps_probe_resp_ie */
8117
if ((pmlmepriv->wps_probe_resp_ie != NULL) && pwps_ie && (wps_ielen > 0)) {
8118
uint wps_offset, remainder_ielen;
8119
u8 *premainder_ie;
8120
8121
wps_offset = (uint)(pwps_ie - cur_network->IEs);
8122
8123
premainder_ie = pwps_ie + wps_ielen;
8124
8125
remainder_ielen = cur_network->IELength - wps_offset - wps_ielen;
8126
8127
_rtw_memcpy(pframe, cur_network->IEs, wps_offset);
8128
pframe += wps_offset;
8129
pattrib->pktlen += wps_offset;
8130
8131
wps_ielen = (uint)pmlmepriv->wps_probe_resp_ie[1];/* to get ie data len */
8132
if ((wps_offset + wps_ielen + 2) <= MAX_IE_SZ) {
8133
_rtw_memcpy(pframe, pmlmepriv->wps_probe_resp_ie, wps_ielen + 2);
8134
pframe += wps_ielen + 2;
8135
pattrib->pktlen += wps_ielen + 2;
8136
}
8137
8138
if ((wps_offset + wps_ielen + 2 + remainder_ielen) <= MAX_IE_SZ) {
8139
_rtw_memcpy(pframe, premainder_ie, remainder_ielen);
8140
pframe += remainder_ielen;
8141
pattrib->pktlen += remainder_ielen;
8142
}
8143
} else {
8144
_rtw_memcpy(pframe, cur_network->IEs, cur_network->IELength);
8145
pframe += cur_network->IELength;
8146
pattrib->pktlen += cur_network->IELength;
8147
}
8148
8149
/* retrieve SSID IE from cur_network->Ssid */
8150
{
8151
u8 *ssid_ie;
8152
sint ssid_ielen;
8153
sint ssid_ielen_diff;
8154
u8 buf[MAX_IE_SZ];
8155
u8 *ies = pmgntframe->buf_addr + TXDESC_OFFSET + sizeof(struct rtw_ieee80211_hdr_3addr);
8156
8157
ssid_ie = rtw_get_ie(ies + _FIXED_IE_LENGTH_, _SSID_IE_, &ssid_ielen,
8158
(pframe - ies) - _FIXED_IE_LENGTH_);
8159
8160
ssid_ielen_diff = cur_network->Ssid.SsidLength - ssid_ielen;
8161
8162
if (ssid_ie && cur_network->Ssid.SsidLength) {
8163
uint remainder_ielen;
8164
u8 *remainder_ie;
8165
remainder_ie = ssid_ie + 2;
8166
remainder_ielen = (pframe - remainder_ie);
8167
8168
if (remainder_ielen > MAX_IE_SZ) {
8169
RTW_WARN(FUNC_ADPT_FMT" remainder_ielen > MAX_IE_SZ\n", FUNC_ADPT_ARG(padapter));
8170
remainder_ielen = MAX_IE_SZ;
8171
}
8172
8173
_rtw_memcpy(buf, remainder_ie, remainder_ielen);
8174
_rtw_memcpy(remainder_ie + ssid_ielen_diff, buf, remainder_ielen);
8175
*(ssid_ie + 1) = cur_network->Ssid.SsidLength;
8176
_rtw_memcpy(ssid_ie + 2, cur_network->Ssid.Ssid, cur_network->Ssid.SsidLength);
8177
8178
pframe += ssid_ielen_diff;
8179
pattrib->pktlen += ssid_ielen_diff;
8180
}
8181
}
8182
#ifdef CONFIG_RTW_REPEATER_SON
8183
rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
8184
#endif
8185
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8186
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_PROBERESP_VENDOR_IE_BIT);
8187
#endif
8188
} else
8189
#endif
8190
{
8191
8192
/* timestamp will be inserted by hardware */
8193
pframe += 8;
8194
pattrib->pktlen += 8;
8195
8196
/* beacon interval: 2 bytes */
8197
8198
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_beacon_interval_from_ie(cur_network->IEs)), 2);
8199
8200
pframe += 2;
8201
pattrib->pktlen += 2;
8202
8203
/* capability info: 2 bytes */
8204
8205
_rtw_memcpy(pframe, (unsigned char *)(rtw_get_capability_from_ie(cur_network->IEs)), 2);
8206
8207
pframe += 2;
8208
pattrib->pktlen += 2;
8209
8210
/* below for ad-hoc mode */
8211
8212
/* SSID */
8213
pframe = rtw_set_ie(pframe, _SSID_IE_, cur_network->Ssid.SsidLength, cur_network->Ssid.Ssid, &pattrib->pktlen);
8214
8215
/* supported rates... */
8216
rate_len = rtw_get_rateset_len(cur_network->SupportedRates);
8217
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, ((rate_len > 8) ? 8 : rate_len), cur_network->SupportedRates, &pattrib->pktlen);
8218
8219
/* DS parameter set */
8220
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, (unsigned char *)&(cur_network->Configuration.DSConfig), &pattrib->pktlen);
8221
8222
if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
8223
u8 erpinfo = 0;
8224
u32 ATIMWindow;
8225
/* IBSS Parameter Set... */
8226
/* ATIMWindow = cur->Configuration.ATIMWindow; */
8227
ATIMWindow = 0;
8228
pframe = rtw_set_ie(pframe, _IBSS_PARA_IE_, 2, (unsigned char *)(&ATIMWindow), &pattrib->pktlen);
8229
8230
/* ERP IE */
8231
pframe = rtw_set_ie(pframe, _ERPINFO_IE_, 1, &erpinfo, &pattrib->pktlen);
8232
}
8233
8234
8235
/* EXTERNDED SUPPORTED RATE */
8236
if (rate_len > 8)
8237
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (rate_len - 8), (cur_network->SupportedRates + 8), &pattrib->pktlen);
8238
8239
8240
/* todo:HT for adhoc */
8241
8242
}
8243
8244
#ifdef CONFIG_RTW_80211K
8245
pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_,
8246
sizeof(padapter->rmpriv.rm_en_cap_def),
8247
padapter->rmpriv.rm_en_cap_def, &pattrib->pktlen);
8248
#endif
8249
8250
#ifdef CONFIG_P2P
8251
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)
8252
/* IOT issue, When wifi_spec is not set, send probe_resp with P2P IE even if probe_req has no P2P IE */
8253
&& (is_valid_p2p_probereq || !padapter->registrypriv.wifi_spec)) {
8254
u32 len;
8255
#ifdef CONFIG_IOCTL_CFG80211
8256
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
8257
/* if pwdinfo->role == P2P_ROLE_DEVICE will call issue_probersp_p2p() */
8258
len = pmlmepriv->p2p_go_probe_resp_ie_len;
8259
if (pmlmepriv->p2p_go_probe_resp_ie && len > 0)
8260
_rtw_memcpy(pframe, pmlmepriv->p2p_go_probe_resp_ie, len);
8261
} else
8262
#endif /* CONFIG_IOCTL_CFG80211 */
8263
{
8264
len = build_probe_resp_p2p_ie(pwdinfo, pframe);
8265
}
8266
8267
pframe += len;
8268
pattrib->pktlen += len;
8269
8270
#ifdef CONFIG_MCC_MODE
8271
pframe = rtw_hal_mcc_append_go_p2p_ie(padapter, pframe, &pattrib->pktlen);
8272
#endif /* CONFIG_MCC_MODE*/
8273
8274
#ifdef CONFIG_WFD
8275
len = rtw_append_probe_resp_wfd_ie(padapter, pframe);
8276
pframe += len;
8277
pattrib->pktlen += len;
8278
#endif
8279
}
8280
#endif /* CONFIG_P2P */
8281
8282
8283
#ifdef CONFIG_AUTO_AP_MODE
8284
{
8285
struct sta_info *psta;
8286
struct sta_priv *pstapriv = &padapter->stapriv;
8287
8288
RTW_INFO("(%s)\n", __FUNCTION__);
8289
8290
/* check rc station */
8291
psta = rtw_get_stainfo(pstapriv, da);
8292
if (psta && psta->isrc && psta->pid > 0) {
8293
u8 RC_OUI[4] = {0x00, 0xE0, 0x4C, 0x0A};
8294
u8 RC_INFO[14] = {0};
8295
/* EID[1] + EID_LEN[1] + RC_OUI[4] + MAC[6] + PairingID[2] + ChannelNum[2] */
8296
u16 cu_ch = (u16)cur_network->Configuration.DSConfig;
8297
8298
RTW_INFO("%s, reply rc(pid=0x%x) device "MAC_FMT" in ch=%d\n", __FUNCTION__,
8299
psta->pid, MAC_ARG(psta->cmn.mac_addr), cu_ch);
8300
8301
/* append vendor specific ie */
8302
_rtw_memcpy(RC_INFO, RC_OUI, sizeof(RC_OUI));
8303
_rtw_memcpy(&RC_INFO[4], mac, ETH_ALEN);
8304
_rtw_memcpy(&RC_INFO[10], (u8 *)&psta->pid, 2);
8305
_rtw_memcpy(&RC_INFO[12], (u8 *)&cu_ch, 2);
8306
8307
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, sizeof(RC_INFO), RC_INFO, &pattrib->pktlen);
8308
}
8309
}
8310
#endif /* CONFIG_AUTO_AP_MODE */
8311
8312
#ifdef CONFIG_RTL8812A
8313
pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen);
8314
#endif/*CONFIG_RTL8812A*/
8315
8316
pattrib->last_txcmdsz = pattrib->pktlen;
8317
8318
8319
dump_mgntframe(padapter, pmgntframe);
8320
8321
return;
8322
8323
}
8324
8325
int _issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps, int wait_ack)
8326
{
8327
int ret = _FAIL;
8328
struct xmit_frame *pmgntframe;
8329
struct pkt_attrib *pattrib;
8330
unsigned char *pframe;
8331
struct rtw_ieee80211_hdr *pwlanhdr;
8332
unsigned short *fctrl;
8333
unsigned char *mac;
8334
unsigned char bssrate[NumRates];
8335
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8336
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8337
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8338
int bssrate_len = 0;
8339
u8 bc_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
8340
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
8341
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
8342
#endif
8343
8344
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8345
goto exit;
8346
8347
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8348
if (pmgntframe == NULL)
8349
goto exit;
8350
8351
/* update attribute */
8352
pattrib = &pmgntframe->attrib;
8353
update_mgntframe_attrib(padapter, pattrib);
8354
8355
8356
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8357
8358
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8359
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8360
8361
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
8362
if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
8363
&& (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
8364
&& (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE))
8365
mac = pwdev_priv->pno_mac_addr;
8366
else
8367
#endif
8368
mac = adapter_mac_addr(padapter);
8369
8370
fctrl = &(pwlanhdr->frame_ctl);
8371
*(fctrl) = 0;
8372
8373
if (da) {
8374
/* unicast probe request frame */
8375
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
8376
_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
8377
} else {
8378
/* broadcast probe request frame */
8379
_rtw_memcpy(pwlanhdr->addr1, bc_addr, ETH_ALEN);
8380
_rtw_memcpy(pwlanhdr->addr3, bc_addr, ETH_ALEN);
8381
}
8382
8383
_rtw_memcpy(pwlanhdr->addr2, mac, ETH_ALEN);
8384
8385
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
8386
if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
8387
&& (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
8388
&& (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) {
8389
#ifdef CONFIG_RTW_DEBUG
8390
RTW_DBG("%s pno_scan_seq_num: %d\n", __func__,
8391
pwdev_priv->pno_scan_seq_num);
8392
#endif
8393
SetSeqNum(pwlanhdr, pwdev_priv->pno_scan_seq_num);
8394
pattrib->seqnum = pwdev_priv->pno_scan_seq_num;
8395
pattrib->qos_en = 1;
8396
pwdev_priv->pno_scan_seq_num++;
8397
} else
8398
#endif
8399
{
8400
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8401
pmlmeext->mgnt_seq++;
8402
}
8403
set_frame_sub_type(pframe, WIFI_PROBEREQ);
8404
8405
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8406
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8407
8408
if (pssid && !MLME_IS_MESH(padapter))
8409
pframe = rtw_set_ie(pframe, _SSID_IE_, pssid->SsidLength, pssid->Ssid, &(pattrib->pktlen));
8410
else
8411
pframe = rtw_set_ie(pframe, _SSID_IE_, 0, NULL, &(pattrib->pktlen));
8412
8413
get_rate_set(padapter, bssrate, &bssrate_len);
8414
8415
if (bssrate_len > 8) {
8416
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
8417
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
8418
} else
8419
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
8420
8421
if (ch)
8422
pframe = rtw_set_ie(pframe, _DSSET_IE_, 1, &ch, &pattrib->pktlen);
8423
8424
#ifdef CONFIG_RTW_MESH
8425
if (MLME_IS_MESH(padapter)) {
8426
if (pssid)
8427
pframe = rtw_set_ie_mesh_id(pframe, &pattrib->pktlen, pssid->Ssid, pssid->SsidLength);
8428
else
8429
pframe = rtw_set_ie_mesh_id(pframe, &pattrib->pktlen, NULL, 0);
8430
}
8431
#endif
8432
8433
if (append_wps) {
8434
/* add wps_ie for wps2.0 */
8435
if (pmlmepriv->wps_probe_req_ie_len > 0 && pmlmepriv->wps_probe_req_ie) {
8436
_rtw_memcpy(pframe, pmlmepriv->wps_probe_req_ie, pmlmepriv->wps_probe_req_ie_len);
8437
pframe += pmlmepriv->wps_probe_req_ie_len;
8438
pattrib->pktlen += pmlmepriv->wps_probe_req_ie_len;
8439
/* pmlmepriv->wps_probe_req_ie_len = 0 ; */ /* reset to zero */
8440
}
8441
}
8442
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8443
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_PROBEREQ_VENDOR_IE_BIT);
8444
#endif
8445
8446
#ifdef CONFIG_RTL8812A
8447
pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
8448
#endif/*CONFIG_RTL8812A*/
8449
8450
8451
pattrib->last_txcmdsz = pattrib->pktlen;
8452
8453
8454
if (wait_ack)
8455
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
8456
else {
8457
dump_mgntframe(padapter, pmgntframe);
8458
ret = _SUCCESS;
8459
}
8460
8461
exit:
8462
return ret;
8463
}
8464
8465
inline void issue_probereq(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da)
8466
{
8467
_issue_probereq(padapter, pssid, da, 0, 1, _FALSE);
8468
}
8469
8470
/*
8471
* wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
8472
* wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
8473
* try_cnt means the maximal TX count to try
8474
*/
8475
int issue_probereq_ex(_adapter *padapter, const NDIS_802_11_SSID *pssid, const u8 *da, u8 ch, bool append_wps,
8476
int try_cnt, int wait_ms)
8477
{
8478
int ret = _FAIL;
8479
int i = 0;
8480
systime start = rtw_get_current_time();
8481
8482
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8483
goto exit;
8484
8485
do {
8486
ret = _issue_probereq(padapter, pssid, da, ch, append_wps, wait_ms > 0 ? _TRUE : _FALSE);
8487
8488
i++;
8489
8490
if (RTW_CANNOT_RUN(padapter))
8491
break;
8492
8493
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
8494
rtw_msleep_os(wait_ms);
8495
8496
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
8497
8498
if (ret != _FAIL) {
8499
ret = _SUCCESS;
8500
#ifndef DBG_XMIT_ACK
8501
goto exit;
8502
#endif
8503
}
8504
8505
if (try_cnt && wait_ms) {
8506
if (da)
8507
RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
8508
FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
8509
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
8510
else
8511
RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
8512
FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
8513
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
8514
}
8515
exit:
8516
return ret;
8517
}
8518
8519
/* if psta == NULL, indiate we are station(client) now... */
8520
void issue_auth(_adapter *padapter, struct sta_info *psta, unsigned short status)
8521
{
8522
struct xmit_frame *pmgntframe;
8523
struct pkt_attrib *pattrib;
8524
unsigned char *pframe;
8525
struct rtw_ieee80211_hdr *pwlanhdr;
8526
unsigned short *fctrl;
8527
unsigned int val32;
8528
unsigned short val16;
8529
int use_shared_key = 0;
8530
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8531
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8532
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8533
8534
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8535
return;
8536
8537
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8538
if (pmgntframe == NULL)
8539
return;
8540
8541
/* update attribute */
8542
pattrib = &pmgntframe->attrib;
8543
update_mgntframe_attrib(padapter, pattrib);
8544
8545
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8546
8547
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8548
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8549
8550
fctrl = &(pwlanhdr->frame_ctl);
8551
*(fctrl) = 0;
8552
8553
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8554
pmlmeext->mgnt_seq++;
8555
set_frame_sub_type(pframe, WIFI_AUTH);
8556
8557
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8558
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8559
8560
8561
if (psta) { /* for AP mode */
8562
#ifdef CONFIG_NATIVEAP_MLME
8563
8564
_rtw_memcpy(pwlanhdr->addr1, psta->cmn.mac_addr, ETH_ALEN);
8565
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8566
_rtw_memcpy(pwlanhdr->addr3, adapter_mac_addr(padapter), ETH_ALEN);
8567
8568
8569
/* setting auth algo number */
8570
val16 = (u16)psta->authalg;
8571
8572
if (status != _STATS_SUCCESSFUL_)
8573
val16 = 0;
8574
8575
if (val16) {
8576
val16 = cpu_to_le16(val16);
8577
use_shared_key = 1;
8578
}
8579
8580
pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8581
8582
/* setting auth seq number */
8583
val16 = (u16)psta->auth_seq;
8584
val16 = cpu_to_le16(val16);
8585
pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8586
8587
/* setting status code... */
8588
val16 = status;
8589
val16 = cpu_to_le16(val16);
8590
pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8591
8592
/* added challenging text... */
8593
if ((psta->auth_seq == 2) && (psta->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1))
8594
pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, psta->chg_txt, &(pattrib->pktlen));
8595
#endif
8596
} else {
8597
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8598
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8599
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
8600
8601
#ifdef CONFIG_RTW_80211R
8602
if (rtw_ft_roam(padapter)) {
8603
/* 2: 802.11R FTAA */
8604
val16 = cpu_to_le16(2);
8605
} else
8606
#endif
8607
{
8608
/* setting auth algo number */
8609
val16 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_Shared) ? 1 : 0; /* 0:OPEN System, 1:Shared key */
8610
if (val16) {
8611
val16 = cpu_to_le16(val16);
8612
use_shared_key = 1;
8613
}
8614
}
8615
8616
/* RTW_INFO("%s auth_algo= %s auth_seq=%d\n",__FUNCTION__,(pmlmeinfo->auth_algo==0)?"OPEN":"SHARED",pmlmeinfo->auth_seq); */
8617
8618
/* setting IV for auth seq #3 */
8619
if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
8620
/* RTW_INFO("==> iv(%d),key_index(%d)\n",pmlmeinfo->iv,pmlmeinfo->key_index); */
8621
val32 = ((pmlmeinfo->iv++) | (pmlmeinfo->key_index << 30));
8622
val32 = cpu_to_le32(val32);
8623
pframe = rtw_set_fixed_ie(pframe, 4, (unsigned char *)&val32, &(pattrib->pktlen));
8624
8625
pattrib->iv_len = 4;
8626
}
8627
8628
pframe = rtw_set_fixed_ie(pframe, _AUTH_ALGM_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8629
8630
/* setting auth seq number */
8631
val16 = pmlmeinfo->auth_seq;
8632
val16 = cpu_to_le16(val16);
8633
pframe = rtw_set_fixed_ie(pframe, _AUTH_SEQ_NUM_, (unsigned char *)&val16, &(pattrib->pktlen));
8634
8635
8636
/* setting status code... */
8637
val16 = status;
8638
val16 = cpu_to_le16(val16);
8639
pframe = rtw_set_fixed_ie(pframe, _STATUS_CODE_, (unsigned char *)&val16, &(pattrib->pktlen));
8640
8641
#ifdef CONFIG_RTW_80211R
8642
rtw_ft_build_auth_req_ies(padapter, pattrib, &pframe);
8643
#endif
8644
8645
/* then checking to see if sending challenging text... */
8646
if ((pmlmeinfo->auth_seq == 3) && (pmlmeinfo->state & WIFI_FW_AUTH_STATE) && (use_shared_key == 1)) {
8647
pframe = rtw_set_ie(pframe, _CHLGETXT_IE_, 128, pmlmeinfo->chg_txt, &(pattrib->pktlen));
8648
8649
SetPrivacy(fctrl);
8650
8651
pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8652
8653
pattrib->encrypt = _WEP40_;
8654
8655
pattrib->icv_len = 4;
8656
8657
pattrib->pktlen += pattrib->icv_len;
8658
8659
}
8660
8661
}
8662
8663
pattrib->last_txcmdsz = pattrib->pktlen;
8664
8665
rtw_wep_encrypt(padapter, (u8 *)pmgntframe);
8666
RTW_INFO("%s\n", __FUNCTION__);
8667
dump_mgntframe(padapter, pmgntframe);
8668
8669
return;
8670
}
8671
8672
8673
void issue_asocrsp(_adapter *padapter, unsigned short status, struct sta_info *pstat, int pkt_type)
8674
{
8675
#ifdef CONFIG_AP_MODE
8676
struct xmit_frame *pmgntframe;
8677
struct rtw_ieee80211_hdr *pwlanhdr;
8678
struct pkt_attrib *pattrib;
8679
unsigned char *pbuf, *pframe;
8680
unsigned short val, ie_status;
8681
unsigned short *fctrl;
8682
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8683
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8684
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
8685
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8686
WLAN_BSSID_EX *pnetwork = &(pmlmeinfo->network);
8687
u8 *ie = pnetwork->IEs;
8688
#ifdef CONFIG_P2P
8689
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8690
#ifdef CONFIG_WFD
8691
u32 wfdielen = 0;
8692
#endif
8693
8694
#endif /* CONFIG_P2P */
8695
8696
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8697
return;
8698
8699
RTW_INFO("%s\n", __FUNCTION__);
8700
8701
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8702
if (pmgntframe == NULL)
8703
return;
8704
8705
/* update attribute */
8706
pattrib = &pmgntframe->attrib;
8707
update_mgntframe_attrib(padapter, pattrib);
8708
8709
8710
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8711
8712
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8713
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8714
8715
fctrl = &(pwlanhdr->frame_ctl);
8716
*(fctrl) = 0;
8717
8718
_rtw_memcpy((void *)GetAddr1Ptr(pwlanhdr), pstat->cmn.mac_addr, ETH_ALEN);
8719
_rtw_memcpy((void *)get_addr2_ptr(pwlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
8720
_rtw_memcpy((void *)GetAddr3Ptr(pwlanhdr), get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8721
8722
8723
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8724
pmlmeext->mgnt_seq++;
8725
if ((pkt_type == WIFI_ASSOCRSP) || (pkt_type == WIFI_REASSOCRSP))
8726
set_frame_sub_type(pwlanhdr, pkt_type);
8727
else
8728
return;
8729
8730
pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8731
pattrib->pktlen += pattrib->hdrlen;
8732
pframe += pattrib->hdrlen;
8733
8734
/* capability */
8735
val = *(unsigned short *)rtw_get_capability_from_ie(ie);
8736
8737
pframe = rtw_set_fixed_ie(pframe, _CAPABILITY_ , (unsigned char *)&val, &(pattrib->pktlen));
8738
8739
ie_status = cpu_to_le16(status);
8740
pframe = rtw_set_fixed_ie(pframe , _STATUS_CODE_ , (unsigned char *)&ie_status, &(pattrib->pktlen));
8741
8742
val = cpu_to_le16(pstat->cmn.aid | BIT(14) | BIT(15));
8743
pframe = rtw_set_fixed_ie(pframe, _ASOC_ID_ , (unsigned char *)&val, &(pattrib->pktlen));
8744
8745
if (pstat->bssratelen <= 8)
8746
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, pstat->bssratelen, pstat->bssrateset, &(pattrib->pktlen));
8747
else {
8748
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_, 8, pstat->bssrateset, &(pattrib->pktlen));
8749
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_, (pstat->bssratelen - 8), pstat->bssrateset + 8, &(pattrib->pktlen));
8750
}
8751
8752
#ifdef CONFIG_IEEE80211W
8753
if (status == _STATS_REFUSED_TEMPORARILY_) {
8754
u8 timeout_itvl[5];
8755
u32 timeout_interval = 3000;
8756
/* Association Comeback time */
8757
timeout_itvl[0] = 0x03;
8758
timeout_interval = cpu_to_le32(timeout_interval);
8759
_rtw_memcpy(timeout_itvl + 1, &timeout_interval, 4);
8760
pframe = rtw_set_ie(pframe, _TIMEOUT_ITVL_IE_, 5, timeout_itvl, &(pattrib->pktlen));
8761
}
8762
#endif /* CONFIG_IEEE80211W */
8763
8764
#ifdef CONFIG_80211N_HT
8765
if ((pstat->flags & WLAN_STA_HT) && (pmlmepriv->htpriv.ht_option)) {
8766
uint ie_len = 0;
8767
8768
/* FILL HT CAP INFO IE */
8769
/* p = hostapd_eid_ht_capabilities_info(hapd, p); */
8770
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_CAPABILITY_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8771
if (pbuf && ie_len > 0) {
8772
_rtw_memcpy(pframe, pbuf, ie_len + 2);
8773
pframe += (ie_len + 2);
8774
pattrib->pktlen += (ie_len + 2);
8775
}
8776
8777
/* FILL HT ADD INFO IE */
8778
/* p = hostapd_eid_ht_operation(hapd, p); */
8779
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _HT_ADD_INFO_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8780
if (pbuf && ie_len > 0) {
8781
_rtw_memcpy(pframe, pbuf, ie_len + 2);
8782
pframe += (ie_len + 2);
8783
pattrib->pktlen += (ie_len + 2);
8784
}
8785
8786
}
8787
#endif
8788
8789
/*adding EXT_CAPAB_IE */
8790
if (pmlmepriv->ext_capab_ie_len > 0) {
8791
uint ie_len = 0;
8792
8793
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, _EXT_CAP_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8794
if (pbuf && ie_len > 0) {
8795
_rtw_memcpy(pframe, pbuf, ie_len + 2);
8796
pframe += (ie_len + 2);
8797
pattrib->pktlen += (ie_len + 2);
8798
}
8799
}
8800
8801
#ifdef CONFIG_80211AC_VHT
8802
if ((pstat->flags & WLAN_STA_VHT) && (pmlmepriv->vhtpriv.vht_option)
8803
&& (pstat->wpa_pairwise_cipher != WPA_CIPHER_TKIP)
8804
&& (pstat->wpa2_pairwise_cipher != WPA_CIPHER_TKIP)) {
8805
u32 ie_len = 0;
8806
8807
/* FILL VHT CAP IE */
8808
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTCapability, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8809
if (pbuf && ie_len > 0) {
8810
_rtw_memcpy(pframe, pbuf, ie_len + 2);
8811
pframe += (ie_len + 2);
8812
pattrib->pktlen += (ie_len + 2);
8813
}
8814
8815
/* FILL VHT OPERATION IE */
8816
pbuf = rtw_get_ie(ie + _BEACON_IE_OFFSET_, EID_VHTOperation, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_));
8817
if (pbuf && ie_len > 0) {
8818
_rtw_memcpy(pframe, pbuf, ie_len + 2);
8819
pframe += (ie_len + 2);
8820
pattrib->pktlen += (ie_len + 2);
8821
}
8822
}
8823
#endif /* CONFIG_80211AC_VHT */
8824
8825
/* FILL WMM IE */
8826
if ((pstat->flags & WLAN_STA_WME) && (pmlmepriv->qospriv.qos_option)) {
8827
uint ie_len = 0;
8828
unsigned char WMM_PARA_IE[] = {0x00, 0x50, 0xf2, 0x02, 0x01, 0x01};
8829
8830
for (pbuf = ie + _BEACON_IE_OFFSET_; ; pbuf += (ie_len + 2)) {
8831
pbuf = rtw_get_ie(pbuf, _VENDOR_SPECIFIC_IE_, &ie_len, (pnetwork->IELength - _BEACON_IE_OFFSET_ - (ie_len + 2)));
8832
if (pbuf && _rtw_memcmp(pbuf + 2, WMM_PARA_IE, 6)) {
8833
_rtw_memcpy(pframe, pbuf, ie_len + 2);
8834
pframe += (ie_len + 2);
8835
pattrib->pktlen += (ie_len + 2);
8836
8837
break;
8838
}
8839
8840
if ((pbuf == NULL) || (ie_len == 0))
8841
break;
8842
}
8843
8844
}
8845
8846
8847
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
8848
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
8849
8850
/* add WPS IE ie for wps 2.0 */
8851
if (pmlmepriv->wps_assoc_resp_ie && pmlmepriv->wps_assoc_resp_ie_len > 0) {
8852
_rtw_memcpy(pframe, pmlmepriv->wps_assoc_resp_ie, pmlmepriv->wps_assoc_resp_ie_len);
8853
8854
pframe += pmlmepriv->wps_assoc_resp_ie_len;
8855
pattrib->pktlen += pmlmepriv->wps_assoc_resp_ie_len;
8856
}
8857
8858
#ifdef CONFIG_P2P
8859
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO) && (pstat->is_p2p_device == _TRUE)) {
8860
u32 len;
8861
8862
if (padapter->wdinfo.driver_interface == DRIVER_CFG80211) {
8863
len = 0;
8864
if (pmlmepriv->p2p_assoc_resp_ie && pmlmepriv->p2p_assoc_resp_ie_len > 0) {
8865
len = pmlmepriv->p2p_assoc_resp_ie_len;
8866
_rtw_memcpy(pframe, pmlmepriv->p2p_assoc_resp_ie, len);
8867
}
8868
} else
8869
len = build_assoc_resp_p2p_ie(pwdinfo, pframe, pstat->p2p_status_code);
8870
pframe += len;
8871
pattrib->pktlen += len;
8872
}
8873
8874
#ifdef CONFIG_WFD
8875
if (rtw_p2p_chk_role(pwdinfo, P2P_ROLE_GO)) {
8876
wfdielen = rtw_append_assoc_resp_wfd_ie(padapter, pframe);
8877
pframe += wfdielen;
8878
pattrib->pktlen += wfdielen;
8879
}
8880
#endif
8881
8882
#endif /* CONFIG_P2P */
8883
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
8884
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCRESP_VENDOR_IE_BIT);
8885
#endif
8886
8887
#ifdef CONFIG_RTL8812A
8888
pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
8889
#endif/*CONFIG_RTL8812A*/
8890
8891
8892
pattrib->last_txcmdsz = pattrib->pktlen;
8893
8894
dump_mgntframe(padapter, pmgntframe);
8895
8896
#endif
8897
}
8898
8899
void _issue_assocreq(_adapter *padapter, u8 is_reassoc)
8900
{
8901
int ret = _FAIL;
8902
struct xmit_frame *pmgntframe;
8903
struct pkt_attrib *pattrib;
8904
unsigned char *pframe;
8905
struct rtw_ieee80211_hdr *pwlanhdr;
8906
unsigned short *fctrl;
8907
unsigned short val16;
8908
unsigned int i, j, index = 0;
8909
unsigned char bssrate[NumRates], sta_bssrate[NumRates];
8910
PNDIS_802_11_VARIABLE_IEs pIE;
8911
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
8912
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
8913
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
8914
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
8915
int bssrate_len = 0, sta_bssrate_len = 0;
8916
u8 vs_ie_length = 0;
8917
#ifdef CONFIG_P2P
8918
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
8919
u8 p2pie[255] = { 0x00 };
8920
u16 p2pielen = 0;
8921
#ifdef CONFIG_WFD
8922
u32 wfdielen = 0;
8923
#endif
8924
#endif /* CONFIG_P2P */
8925
8926
#ifdef CONFIG_DFS
8927
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
8928
u16 cap;
8929
8930
/* Dot H */
8931
u8 pow_cap_ele[2] = { 0x00 };
8932
u8 sup_ch[30 * 2] = {0x00 }, sup_ch_idx = 0, idx_5g = 2; /* For supported channel */
8933
#endif /* CONFIG_DFS */
8934
8935
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
8936
goto exit;
8937
8938
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
8939
if (pmgntframe == NULL)
8940
goto exit;
8941
8942
/* update attribute */
8943
pattrib = &pmgntframe->attrib;
8944
update_mgntframe_attrib(padapter, pattrib);
8945
8946
8947
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
8948
8949
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
8950
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
8951
8952
fctrl = &(pwlanhdr->frame_ctl);
8953
*(fctrl) = 0;
8954
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8955
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
8956
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8957
8958
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
8959
pmlmeext->mgnt_seq++;
8960
if (is_reassoc == _TRUE)
8961
set_frame_sub_type(pframe, WIFI_REASSOCREQ);
8962
else
8963
set_frame_sub_type(pframe, WIFI_ASSOCREQ);
8964
8965
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
8966
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
8967
8968
/* caps */
8969
8970
#ifdef CONFIG_DFS
8971
_rtw_memcpy(&cap, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8972
cap |= cap_SpecMgmt;
8973
_rtw_memcpy(pframe, &cap, 2);
8974
#else
8975
_rtw_memcpy(pframe, rtw_get_capability_from_ie(pmlmeinfo->network.IEs), 2);
8976
#endif /* CONFIG_DFS */
8977
8978
pframe += 2;
8979
pattrib->pktlen += 2;
8980
8981
/* listen interval */
8982
/* todo: listen interval for power saving */
8983
val16 = cpu_to_le16(3);
8984
_rtw_memcpy(pframe , (unsigned char *)&val16, 2);
8985
pframe += 2;
8986
pattrib->pktlen += 2;
8987
8988
/*Construct Current AP Field for Reassoc-Req only*/
8989
if (is_reassoc == _TRUE) {
8990
_rtw_memcpy(pframe, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
8991
pframe += ETH_ALEN;
8992
pattrib->pktlen += ETH_ALEN;
8993
}
8994
8995
/* SSID */
8996
pframe = rtw_set_ie(pframe, _SSID_IE_, pmlmeinfo->network.Ssid.SsidLength, pmlmeinfo->network.Ssid.Ssid, &(pattrib->pktlen));
8997
8998
#ifdef CONFIG_DFS
8999
/* Dot H */
9000
if (pmlmeext->cur_channel > 14) {
9001
pow_cap_ele[0] = 13; /* Minimum transmit power capability */
9002
pow_cap_ele[1] = 21; /* Maximum transmit power capability */
9003
pframe = rtw_set_ie(pframe, EID_PowerCap, 2, pow_cap_ele, &(pattrib->pktlen));
9004
9005
/* supported channels */
9006
while (sup_ch_idx < rfctl->max_chan_nums && rfctl->channel_set[sup_ch_idx].ChannelNum != 0) {
9007
if (rfctl->channel_set[sup_ch_idx].ChannelNum <= 14) {
9008
/* TODO: fix 2.4G supported channel when channel doesn't start from 1 and continuous */
9009
sup_ch[0] = 1; /* First channel number */
9010
sup_ch[1] = rfctl->channel_set[sup_ch_idx].ChannelNum; /* Number of channel */
9011
} else {
9012
sup_ch[idx_5g++] = rfctl->channel_set[sup_ch_idx].ChannelNum;
9013
sup_ch[idx_5g++] = 1;
9014
}
9015
sup_ch_idx++;
9016
}
9017
pframe = rtw_set_ie(pframe, EID_SupportedChannels, idx_5g, sup_ch, &(pattrib->pktlen));
9018
}
9019
#endif /* CONFIG_DFS */
9020
9021
/* supported rate & extended supported rate */
9022
9023
#if 1 /* Check if the AP's supported rates are also supported by STA. */
9024
get_rate_set(padapter, sta_bssrate, &sta_bssrate_len);
9025
/* RTW_INFO("sta_bssrate_len=%d\n", sta_bssrate_len); */
9026
9027
if (pmlmeext->cur_channel == 14) /* for JAPAN, channel 14 can only uses B Mode(CCK) */
9028
sta_bssrate_len = 4;
9029
9030
9031
/* for (i = 0; i < sta_bssrate_len; i++) { */
9032
/* RTW_INFO("sta_bssrate[%d]=%02X\n", i, sta_bssrate[i]); */
9033
/* } */
9034
9035
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
9036
if (pmlmeinfo->network.SupportedRates[i] == 0)
9037
break;
9038
RTW_INFO("network.SupportedRates[%d]=%02X\n", i, pmlmeinfo->network.SupportedRates[i]);
9039
}
9040
9041
9042
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
9043
if (pmlmeinfo->network.SupportedRates[i] == 0)
9044
break;
9045
9046
9047
/* Check if the AP's supported rates are also supported by STA. */
9048
for (j = 0; j < sta_bssrate_len; j++) {
9049
/* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
9050
if ((pmlmeinfo->network.SupportedRates[i] | IEEE80211_BASIC_RATE_MASK)
9051
== (sta_bssrate[j] | IEEE80211_BASIC_RATE_MASK)) {
9052
/* RTW_INFO("match i = %d, j=%d\n", i, j); */
9053
break;
9054
} else {
9055
/* RTW_INFO("not match: %02X != %02X\n", (pmlmeinfo->network.SupportedRates[i]|IEEE80211_BASIC_RATE_MASK), (sta_bssrate[j]|IEEE80211_BASIC_RATE_MASK)); */
9056
}
9057
}
9058
9059
if (j == sta_bssrate_len) {
9060
/* the rate is not supported by STA */
9061
RTW_INFO("%s(): the rate[%d]=%02X is not supported by STA!\n", __FUNCTION__, i, pmlmeinfo->network.SupportedRates[i]);
9062
} else {
9063
/* the rate is supported by STA */
9064
bssrate[index++] = pmlmeinfo->network.SupportedRates[i];
9065
}
9066
}
9067
9068
bssrate_len = index;
9069
RTW_INFO("bssrate_len = %d\n", bssrate_len);
9070
9071
#else /* Check if the AP's supported rates are also supported by STA. */
9072
#if 0
9073
get_rate_set(padapter, bssrate, &bssrate_len);
9074
#else
9075
for (bssrate_len = 0; bssrate_len < NumRates; bssrate_len++) {
9076
if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0)
9077
break;
9078
9079
if (pmlmeinfo->network.SupportedRates[bssrate_len] == 0x2C) /* Avoid the proprietary data rate (22Mbps) of Handlink WSG-4000 AP */
9080
break;
9081
9082
bssrate[bssrate_len] = pmlmeinfo->network.SupportedRates[bssrate_len];
9083
}
9084
#endif
9085
#endif /* Check if the AP's supported rates are also supported by STA. */
9086
9087
if ((bssrate_len == 0) && (pmlmeinfo->network.SupportedRates[0] != 0)) {
9088
rtw_free_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
9089
rtw_free_xmitframe(pxmitpriv, pmgntframe);
9090
goto exit; /* don't connect to AP if no joint supported rate */
9091
}
9092
9093
9094
if (bssrate_len > 8) {
9095
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , 8, bssrate, &(pattrib->pktlen));
9096
pframe = rtw_set_ie(pframe, _EXT_SUPPORTEDRATES_IE_ , (bssrate_len - 8), (bssrate + 8), &(pattrib->pktlen));
9097
} else if (bssrate_len > 0)
9098
pframe = rtw_set_ie(pframe, _SUPPORTEDRATES_IE_ , bssrate_len , bssrate, &(pattrib->pktlen));
9099
else
9100
RTW_INFO("%s: Connect to AP without 11b and 11g data rate!\n", __FUNCTION__);
9101
9102
#ifdef CONFIG_RTW_80211K
9103
if (pmlmeinfo->network.PhyInfo.rm_en_cap[0] /* RM Enabled Capabilities */
9104
| pmlmeinfo->network.PhyInfo.rm_en_cap[1]
9105
| pmlmeinfo->network.PhyInfo.rm_en_cap[2]
9106
| pmlmeinfo->network.PhyInfo.rm_en_cap[3]
9107
| pmlmeinfo->network.PhyInfo.rm_en_cap[4])
9108
pframe = rtw_set_ie(pframe, _EID_RRM_EN_CAP_IE_, 5,
9109
(u8 *)padapter->rmpriv.rm_en_cap_def, &(pattrib->pktlen));
9110
#endif /* CONFIG_RTW_80211K */
9111
9112
/* vendor specific IE, such as WPA, WMM, WPS */
9113
for (i = sizeof(NDIS_802_11_FIXED_IEs); i < pmlmeinfo->network.IELength;) {
9114
pIE = (PNDIS_802_11_VARIABLE_IEs)(pmlmeinfo->network.IEs + i);
9115
9116
switch (pIE->ElementID) {
9117
case _VENDOR_SPECIFIC_IE_:
9118
if ((_rtw_memcmp(pIE->data, RTW_WPA_OUI, 4)) ||
9119
(_rtw_memcmp(pIE->data, WMM_OUI, 4)) ||
9120
(_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
9121
vs_ie_length = pIE->Length;
9122
if ((!padapter->registrypriv.wifi_spec) && (_rtw_memcmp(pIE->data, WPS_OUI, 4))) {
9123
/* Commented by Kurt 20110629 */
9124
/* In some older APs, WPS handshake */
9125
/* would be fail if we append vender extensions informations to AP */
9126
9127
vs_ie_length = 14;
9128
}
9129
9130
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, vs_ie_length, pIE->data, &(pattrib->pktlen));
9131
}
9132
break;
9133
9134
case EID_WPA2:
9135
#ifdef CONFIG_RTW_80211R
9136
if ((is_reassoc) && (rtw_ft_roam(padapter))) {
9137
rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe);
9138
} else
9139
#endif
9140
{
9141
#ifdef CONFIG_IOCTL_CFG80211
9142
if (rtw_sec_chk_auth_alg(padapter, WLAN_AUTH_OPEN) &&
9143
rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) {
9144
s32 entry = rtw_cached_pmkid(padapter, pmlmepriv->assoc_bssid);
9145
9146
rtw_rsn_sync_pmkid(padapter, (u8 *)pIE, (pIE->Length + 2), entry);
9147
}
9148
#endif /* CONFIG_IOCTL_CFG80211 */
9149
9150
pframe = rtw_set_ie(pframe, EID_WPA2, pIE->Length, pIE->data, &(pattrib->pktlen));
9151
}
9152
break;
9153
#ifdef CONFIG_80211N_HT
9154
case EID_HTCapability:
9155
if (padapter->mlmepriv.htpriv.ht_option == _TRUE) {
9156
if (!(is_ap_in_tkip(padapter))) {
9157
_rtw_memcpy(&(pmlmeinfo->HT_caps), pIE->data, sizeof(struct HT_caps_element));
9158
9159
pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info = cpu_to_le16(pmlmeinfo->HT_caps.u.HT_cap_element.HT_caps_info);
9160
9161
pframe = rtw_set_ie(pframe, EID_HTCapability, pIE->Length , (u8 *)(&(pmlmeinfo->HT_caps)), &(pattrib->pktlen));
9162
}
9163
}
9164
break;
9165
9166
case EID_EXTCapability:
9167
if (padapter->mlmepriv.htpriv.ht_option == _TRUE)
9168
pframe = rtw_set_ie(pframe, EID_EXTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
9169
break;
9170
#endif /* CONFIG_80211N_HT */
9171
#ifdef CONFIG_80211AC_VHT
9172
case EID_VHTCapability:
9173
if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9174
pframe = rtw_set_ie(pframe, EID_VHTCapability, pIE->Length, pIE->data, &(pattrib->pktlen));
9175
break;
9176
9177
case EID_OpModeNotification:
9178
if (padapter->mlmepriv.vhtpriv.vht_option == _TRUE)
9179
pframe = rtw_set_ie(pframe, EID_OpModeNotification, pIE->Length, pIE->data, &(pattrib->pktlen));
9180
break;
9181
#endif /* CONFIG_80211AC_VHT */
9182
default:
9183
break;
9184
}
9185
9186
i += (pIE->Length + 2);
9187
}
9188
9189
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK)
9190
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, 6 , REALTEK_96B_IE, &(pattrib->pktlen));
9191
9192
9193
#ifdef CONFIG_WAPI_SUPPORT
9194
rtw_build_assoc_req_wapi_ie(padapter, pframe, pattrib);
9195
#endif
9196
9197
9198
#ifdef CONFIG_P2P
9199
9200
#ifdef CONFIG_IOCTL_CFG80211
9201
if (adapter_wdev_data(padapter)->p2p_enabled && pwdinfo->driver_interface == DRIVER_CFG80211) {
9202
if (pmlmepriv->p2p_assoc_req_ie && pmlmepriv->p2p_assoc_req_ie_len > 0) {
9203
_rtw_memcpy(pframe, pmlmepriv->p2p_assoc_req_ie, pmlmepriv->p2p_assoc_req_ie_len);
9204
pframe += pmlmepriv->p2p_assoc_req_ie_len;
9205
pattrib->pktlen += pmlmepriv->p2p_assoc_req_ie_len;
9206
}
9207
} else
9208
#endif /* CONFIG_IOCTL_CFG80211 */
9209
{
9210
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE) && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_IDLE)) {
9211
/* Should add the P2P IE in the association request frame. */
9212
/* P2P OUI */
9213
9214
p2pielen = 0;
9215
p2pie[p2pielen++] = 0x50;
9216
p2pie[p2pielen++] = 0x6F;
9217
p2pie[p2pielen++] = 0x9A;
9218
p2pie[p2pielen++] = 0x09; /* WFA P2P v1.0 */
9219
9220
/* Commented by Albert 20101109 */
9221
/* According to the P2P Specification, the association request frame should contain 3 P2P attributes */
9222
/* 1. P2P Capability */
9223
/* 2. Extended Listen Timing */
9224
/* 3. Device Info */
9225
/* Commented by Albert 20110516 */
9226
/* 4. P2P Interface */
9227
9228
/* P2P Capability */
9229
/* Type: */
9230
p2pie[p2pielen++] = P2P_ATTR_CAPABILITY;
9231
9232
/* Length: */
9233
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0002);
9234
p2pielen += 2;
9235
9236
/* Value: */
9237
/* Device Capability Bitmap, 1 byte */
9238
p2pie[p2pielen++] = DMP_P2P_DEVCAP_SUPPORT;
9239
9240
/* Group Capability Bitmap, 1 byte */
9241
if (pwdinfo->persistent_supported)
9242
p2pie[p2pielen++] = P2P_GRPCAP_PERSISTENT_GROUP | DMP_P2P_GRPCAP_SUPPORT;
9243
else
9244
p2pie[p2pielen++] = DMP_P2P_GRPCAP_SUPPORT;
9245
9246
/* Extended Listen Timing */
9247
/* Type: */
9248
p2pie[p2pielen++] = P2P_ATTR_EX_LISTEN_TIMING;
9249
9250
/* Length: */
9251
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x0004);
9252
p2pielen += 2;
9253
9254
/* Value: */
9255
/* Availability Period */
9256
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9257
p2pielen += 2;
9258
9259
/* Availability Interval */
9260
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0xFFFF);
9261
p2pielen += 2;
9262
9263
/* Device Info */
9264
/* Type: */
9265
p2pie[p2pielen++] = P2P_ATTR_DEVICE_INFO;
9266
9267
/* Length: */
9268
/* 21->P2P Device Address (6bytes) + Config Methods (2bytes) + Primary Device Type (8bytes) */
9269
/* + NumofSecondDevType (1byte) + WPS Device Name ID field (2bytes) + WPS Device Name Len field (2bytes) */
9270
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(21 + pwdinfo->device_name_len);
9271
p2pielen += 2;
9272
9273
/* Value: */
9274
/* P2P Device Address */
9275
_rtw_memcpy(p2pie + p2pielen, adapter_mac_addr(padapter), ETH_ALEN);
9276
p2pielen += ETH_ALEN;
9277
9278
/* Config Method */
9279
/* This field should be big endian. Noted by P2P specification. */
9280
if ((pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_PEER_DISPLAY_PIN) ||
9281
(pwdinfo->ui_got_wps_info == P2P_GOT_WPSINFO_SELF_DISPLAY_PIN))
9282
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_DISPLAY);
9283
else
9284
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_CONFIG_METHOD_PBC);
9285
9286
p2pielen += 2;
9287
9288
/* Primary Device Type */
9289
/* Category ID */
9290
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_CID_MULIT_MEDIA);
9291
p2pielen += 2;
9292
9293
/* OUI */
9294
*(u32 *)(p2pie + p2pielen) = cpu_to_be32(WPSOUI);
9295
p2pielen += 4;
9296
9297
/* Sub Category ID */
9298
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_PDT_SCID_MEDIA_SERVER);
9299
p2pielen += 2;
9300
9301
/* Number of Secondary Device Types */
9302
p2pie[p2pielen++] = 0x00; /* No Secondary Device Type List */
9303
9304
/* Device Name */
9305
/* Type: */
9306
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(WPS_ATTR_DEVICE_NAME);
9307
p2pielen += 2;
9308
9309
/* Length: */
9310
*(u16 *)(p2pie + p2pielen) = cpu_to_be16(pwdinfo->device_name_len);
9311
p2pielen += 2;
9312
9313
/* Value: */
9314
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_name, pwdinfo->device_name_len);
9315
p2pielen += pwdinfo->device_name_len;
9316
9317
/* P2P Interface */
9318
/* Type: */
9319
p2pie[p2pielen++] = P2P_ATTR_INTERFACE;
9320
9321
/* Length: */
9322
*(u16 *)(p2pie + p2pielen) = cpu_to_le16(0x000D);
9323
p2pielen += 2;
9324
9325
/* Value: */
9326
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Device Address */
9327
p2pielen += ETH_ALEN;
9328
9329
p2pie[p2pielen++] = 1; /* P2P Interface Address Count */
9330
9331
_rtw_memcpy(p2pie + p2pielen, pwdinfo->device_addr, ETH_ALEN); /* P2P Interface Address List */
9332
p2pielen += ETH_ALEN;
9333
9334
pframe = rtw_set_ie(pframe, _VENDOR_SPECIFIC_IE_, p2pielen, (unsigned char *) p2pie, &pattrib->pktlen);
9335
}
9336
}
9337
9338
#ifdef CONFIG_WFD
9339
wfdielen = rtw_append_assoc_req_wfd_ie(padapter, pframe);
9340
pframe += wfdielen;
9341
pattrib->pktlen += wfdielen;
9342
#endif
9343
#endif /* CONFIG_P2P */
9344
9345
#ifdef CONFIG_RTW_REPEATER_SON
9346
rtw_rson_append_ie(padapter, pframe, &pattrib->pktlen);
9347
#endif
9348
#ifdef CONFIG_APPEND_VENDOR_IE_ENABLE
9349
pattrib->pktlen += rtw_build_vendor_ie(padapter , &pframe , WIFI_ASSOCREQ_VENDOR_IE_BIT);
9350
#endif
9351
9352
#ifdef CONFIG_RTL8812A
9353
pframe = rtw_hal_set_8812a_vendor_ie(padapter, pframe, &pattrib->pktlen );
9354
#endif/*CONFIG_RTL8812A*/
9355
9356
#ifdef CONFIG_RTW_80211R
9357
rtw_ft_build_assoc_req_ies(padapter, is_reassoc, pattrib, &pframe);
9358
#endif
9359
9360
pattrib->last_txcmdsz = pattrib->pktlen;
9361
dump_mgntframe(padapter, pmgntframe);
9362
9363
ret = _SUCCESS;
9364
9365
exit:
9366
if (ret == _SUCCESS)
9367
rtw_buf_update(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len, (u8 *)pwlanhdr, pattrib->pktlen);
9368
else
9369
rtw_buf_free(&pmlmepriv->assoc_req, &pmlmepriv->assoc_req_len);
9370
9371
return;
9372
}
9373
9374
void issue_assocreq(_adapter *padapter)
9375
{
9376
_issue_assocreq(padapter, _FALSE);
9377
}
9378
9379
void issue_reassocreq(_adapter *padapter)
9380
{
9381
_issue_assocreq(padapter, _TRUE);
9382
}
9383
9384
/* when wait_ack is ture, this function shoule be called at process context */
9385
static int _issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int wait_ack)
9386
{
9387
int ret = _FAIL;
9388
struct xmit_frame *pmgntframe;
9389
struct pkt_attrib *pattrib;
9390
unsigned char *pframe;
9391
struct rtw_ieee80211_hdr *pwlanhdr;
9392
unsigned short *fctrl;
9393
struct xmit_priv *pxmitpriv;
9394
struct mlme_ext_priv *pmlmeext;
9395
struct mlme_ext_info *pmlmeinfo;
9396
u8 a4_shift;
9397
9398
/* RTW_INFO("%s:%d\n", __FUNCTION__, power_mode); */
9399
9400
if (!padapter)
9401
goto exit;
9402
9403
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9404
goto exit;
9405
9406
pxmitpriv = &(padapter->xmitpriv);
9407
pmlmeext = &(padapter->mlmeextpriv);
9408
pmlmeinfo = &(pmlmeext->mlmext_info);
9409
9410
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9411
if (pmgntframe == NULL)
9412
goto exit;
9413
9414
/* update attribute */
9415
pattrib = &pmgntframe->attrib;
9416
update_mgntframe_attrib(padapter, pattrib);
9417
pattrib->retry_ctrl = _FALSE;
9418
9419
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9420
9421
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9422
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9423
9424
fctrl = &(pwlanhdr->frame_ctl);
9425
*(fctrl) = 0;
9426
9427
if (MLME_IS_AP(padapter))
9428
SetFrDs(fctrl);
9429
else if (MLME_IS_STA(padapter))
9430
SetToDs(fctrl);
9431
else if (MLME_IS_MESH(padapter)) {
9432
SetToDs(fctrl);
9433
SetFrDs(fctrl);
9434
}
9435
9436
if (power_mode)
9437
SetPwrMgt(fctrl);
9438
9439
if (get_tofr_ds(fctrl) == 3) {
9440
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9441
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9442
_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
9443
_rtw_memcpy(pwlanhdr->addr4, adapter_mac_addr(padapter), ETH_ALEN);
9444
a4_shift = ETH_ALEN;
9445
pattrib->hdrlen += ETH_ALEN;
9446
} else {
9447
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9448
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9449
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9450
a4_shift = 0;
9451
}
9452
9453
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9454
pmlmeext->mgnt_seq++;
9455
set_frame_sub_type(pframe, WIFI_DATA_NULL);
9456
9457
pframe += sizeof(struct rtw_ieee80211_hdr_3addr) + a4_shift;
9458
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr) + a4_shift;
9459
9460
pattrib->last_txcmdsz = pattrib->pktlen;
9461
9462
if (wait_ack)
9463
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9464
else {
9465
dump_mgntframe(padapter, pmgntframe);
9466
ret = _SUCCESS;
9467
}
9468
9469
exit:
9470
return ret;
9471
}
9472
9473
/*
9474
* When wait_ms > 0, this function should be called at process context
9475
* wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9476
* wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9477
* try_cnt means the maximal TX count to try
9478
* da == NULL for station mode
9479
*/
9480
int issue_nulldata(_adapter *padapter, unsigned char *da, unsigned int power_mode, int try_cnt, int wait_ms)
9481
{
9482
int ret = _FAIL;
9483
int i = 0;
9484
systime start = rtw_get_current_time();
9485
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9486
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9487
9488
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9489
goto exit;
9490
9491
/* da == NULL, assum it's null data for sta to ap */
9492
if (da == NULL)
9493
da = get_my_bssid(&(pmlmeinfo->network));
9494
9495
do {
9496
ret = _issue_nulldata(padapter, da, power_mode, wait_ms > 0 ? _TRUE : _FALSE);
9497
9498
i++;
9499
9500
if (RTW_CANNOT_RUN(padapter))
9501
break;
9502
9503
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9504
rtw_msleep_os(wait_ms);
9505
9506
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9507
9508
if (ret != _FAIL) {
9509
ret = _SUCCESS;
9510
#ifndef DBG_XMIT_ACK
9511
goto exit;
9512
#endif
9513
}
9514
9515
if (try_cnt && wait_ms) {
9516
if (da)
9517
RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9518
FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9519
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9520
else
9521
RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9522
FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9523
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9524
}
9525
exit:
9526
return ret;
9527
}
9528
9529
/* when wait_ack is ture, this function shoule be called at process context */
9530
static int _issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, u8 ps, int wait_ack)
9531
{
9532
int ret = _FAIL;
9533
struct xmit_frame *pmgntframe;
9534
struct pkt_attrib *pattrib;
9535
unsigned char *pframe;
9536
struct rtw_ieee80211_hdr *pwlanhdr;
9537
unsigned short *fctrl, *qc;
9538
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9539
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9540
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9541
u8 a4_shift;
9542
9543
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9544
goto exit;
9545
9546
/* RTW_INFO("%s\n", __FUNCTION__); */
9547
9548
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9549
if (pmgntframe == NULL)
9550
goto exit;
9551
9552
/* update attribute */
9553
pattrib = &pmgntframe->attrib;
9554
update_mgntframe_attrib(padapter, pattrib);
9555
9556
pattrib->hdrlen += 2;
9557
pattrib->qos_en = _TRUE;
9558
pattrib->eosp = 1;
9559
pattrib->ack_policy = 0;
9560
pattrib->mdata = 0;
9561
9562
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9563
9564
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9565
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9566
9567
fctrl = &(pwlanhdr->frame_ctl);
9568
*(fctrl) = 0;
9569
9570
if (MLME_IS_AP(padapter))
9571
SetFrDs(fctrl);
9572
else if (MLME_IS_STA(padapter))
9573
SetToDs(fctrl);
9574
else if (MLME_IS_MESH(padapter)) {
9575
SetToDs(fctrl);
9576
SetFrDs(fctrl);
9577
}
9578
9579
if (ps)
9580
SetPwrMgt(fctrl);
9581
9582
if (pattrib->mdata)
9583
SetMData(fctrl);
9584
9585
if (get_tofr_ds(fctrl) == 3) {
9586
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9587
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9588
_rtw_memcpy(pwlanhdr->addr3, da, ETH_ALEN);
9589
_rtw_memcpy(pwlanhdr->addr4, adapter_mac_addr(padapter), ETH_ALEN);
9590
a4_shift = ETH_ALEN;
9591
pattrib->hdrlen += ETH_ALEN;
9592
} else {
9593
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9594
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9595
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9596
a4_shift = 0;
9597
}
9598
9599
qc = (unsigned short *)(pframe + pattrib->hdrlen - 2);
9600
9601
SetPriority(qc, tid);
9602
9603
SetEOSP(qc, pattrib->eosp);
9604
9605
SetAckpolicy(qc, pattrib->ack_policy);
9606
9607
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9608
pmlmeext->mgnt_seq++;
9609
set_frame_sub_type(pframe, WIFI_QOS_DATA_NULL);
9610
9611
pframe += sizeof(struct rtw_ieee80211_hdr_3addr_qos) + a4_shift;
9612
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr_qos) + a4_shift;
9613
9614
pattrib->last_txcmdsz = pattrib->pktlen;
9615
9616
if (wait_ack)
9617
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9618
else {
9619
dump_mgntframe(padapter, pmgntframe);
9620
ret = _SUCCESS;
9621
}
9622
9623
exit:
9624
return ret;
9625
}
9626
9627
/*
9628
* when wait_ms >0 , this function should be called at process context
9629
* wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9630
* wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9631
* try_cnt means the maximal TX count to try
9632
* da == NULL for station mode
9633
*/
9634
int issue_qos_nulldata(_adapter *padapter, unsigned char *da, u16 tid, u8 ps, int try_cnt, int wait_ms)
9635
{
9636
int ret = _FAIL;
9637
int i = 0;
9638
systime start = rtw_get_current_time();
9639
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9640
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9641
9642
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9643
goto exit;
9644
9645
/* da == NULL, assum it's null data for sta to ap*/
9646
if (da == NULL)
9647
da = get_my_bssid(&(pmlmeinfo->network));
9648
9649
do {
9650
ret = _issue_qos_nulldata(padapter, da, tid, ps, wait_ms > 0 ? _TRUE : _FALSE);
9651
9652
i++;
9653
9654
if (RTW_CANNOT_RUN(padapter))
9655
break;
9656
9657
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9658
rtw_msleep_os(wait_ms);
9659
9660
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9661
9662
if (ret != _FAIL) {
9663
ret = _SUCCESS;
9664
#ifndef DBG_XMIT_ACK
9665
goto exit;
9666
#endif
9667
}
9668
9669
if (try_cnt && wait_ms) {
9670
if (da)
9671
RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9672
FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9673
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9674
else
9675
RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9676
FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9677
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9678
}
9679
exit:
9680
return ret;
9681
}
9682
9683
static int _issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason, u8 wait_ack, u8 key_type)
9684
{
9685
struct xmit_frame *pmgntframe;
9686
struct pkt_attrib *pattrib;
9687
unsigned char *pframe;
9688
struct rtw_ieee80211_hdr *pwlanhdr;
9689
unsigned short *fctrl;
9690
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9691
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9692
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9693
int ret = _FAIL;
9694
#ifdef CONFIG_P2P
9695
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
9696
#endif /* CONFIG_P2P */
9697
9698
/* RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da)); */
9699
9700
#ifdef CONFIG_P2P
9701
if (!(rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE)) && (pwdinfo->rx_invitereq_info.scan_op_ch_only)) {
9702
_cancel_timer_ex(&pwdinfo->reset_ch_sitesurvey);
9703
_set_timer(&pwdinfo->reset_ch_sitesurvey, 10);
9704
}
9705
#endif /* CONFIG_P2P */
9706
9707
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9708
goto exit;
9709
9710
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9711
if (pmgntframe == NULL)
9712
goto exit;
9713
9714
/* update attribute */
9715
pattrib = &pmgntframe->attrib;
9716
update_mgntframe_attrib(padapter, pattrib);
9717
pattrib->retry_ctrl = _FALSE;
9718
pattrib->key_type = key_type;
9719
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9720
9721
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9722
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9723
9724
fctrl = &(pwlanhdr->frame_ctl);
9725
*(fctrl) = 0;
9726
9727
_rtw_memcpy(pwlanhdr->addr1, da, ETH_ALEN);
9728
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9729
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9730
9731
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9732
pmlmeext->mgnt_seq++;
9733
set_frame_sub_type(pframe, WIFI_DEAUTH);
9734
9735
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9736
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9737
9738
reason = cpu_to_le16(reason);
9739
pframe = rtw_set_fixed_ie(pframe, _RSON_CODE_ , (unsigned char *)&reason, &(pattrib->pktlen));
9740
9741
pattrib->last_txcmdsz = pattrib->pktlen;
9742
9743
9744
if (wait_ack)
9745
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
9746
else {
9747
dump_mgntframe(padapter, pmgntframe);
9748
ret = _SUCCESS;
9749
}
9750
9751
exit:
9752
return ret;
9753
}
9754
9755
int issue_deauth(_adapter *padapter, unsigned char *da, unsigned short reason)
9756
{
9757
RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9758
return _issue_deauth(padapter, da, reason, _FALSE, IEEE80211W_RIGHT_KEY);
9759
}
9760
9761
#ifdef CONFIG_IEEE80211W
9762
int issue_deauth_11w(_adapter *padapter, unsigned char *da, unsigned short reason, u8 key_type)
9763
{
9764
RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(da));
9765
return _issue_deauth(padapter, da, reason, _FALSE, key_type);
9766
}
9767
#endif /* CONFIG_IEEE80211W */
9768
9769
/*
9770
* wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
9771
* wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
9772
* try_cnt means the maximal TX count to try
9773
*/
9774
int issue_deauth_ex(_adapter *padapter, u8 *da, unsigned short reason, int try_cnt,
9775
int wait_ms)
9776
{
9777
int ret = _FAIL;
9778
int i = 0;
9779
systime start = rtw_get_current_time();
9780
9781
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9782
goto exit;
9783
9784
do {
9785
ret = _issue_deauth(padapter, da, reason, wait_ms > 0 ? _TRUE : _FALSE, IEEE80211W_RIGHT_KEY);
9786
9787
i++;
9788
9789
if (RTW_CANNOT_RUN(padapter))
9790
break;
9791
9792
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
9793
rtw_msleep_os(wait_ms);
9794
9795
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
9796
9797
if (ret != _FAIL) {
9798
ret = _SUCCESS;
9799
#ifndef DBG_XMIT_ACK
9800
goto exit;
9801
#endif
9802
}
9803
9804
if (try_cnt && wait_ms) {
9805
if (da)
9806
RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", ch:%u%s, %d/%d in %u ms\n",
9807
FUNC_ADPT_ARG(padapter), MAC_ARG(da), rtw_get_oper_ch(padapter),
9808
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9809
else
9810
RTW_INFO(FUNC_ADPT_FMT", ch:%u%s, %d/%d in %u ms\n",
9811
FUNC_ADPT_ARG(padapter), rtw_get_oper_ch(padapter),
9812
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
9813
}
9814
exit:
9815
return ret;
9816
}
9817
9818
void issue_action_spct_ch_switch(_adapter *padapter, u8 *ra, u8 new_ch, u8 ch_offset)
9819
{
9820
struct xmit_frame *pmgntframe;
9821
struct pkt_attrib *pattrib;
9822
unsigned char *pframe;
9823
struct rtw_ieee80211_hdr *pwlanhdr;
9824
unsigned short *fctrl;
9825
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9826
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9827
9828
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9829
return;
9830
9831
RTW_INFO(FUNC_NDEV_FMT" ra="MAC_FMT", ch:%u, offset:%u\n",
9832
FUNC_NDEV_ARG(padapter->pnetdev), MAC_ARG(ra), new_ch, ch_offset);
9833
9834
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9835
if (pmgntframe == NULL)
9836
return;
9837
9838
/* update attribute */
9839
pattrib = &pmgntframe->attrib;
9840
update_mgntframe_attrib(padapter, pattrib);
9841
9842
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9843
9844
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9845
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9846
9847
fctrl = &(pwlanhdr->frame_ctl);
9848
*(fctrl) = 0;
9849
9850
_rtw_memcpy(pwlanhdr->addr1, ra, ETH_ALEN); /* RA */
9851
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
9852
_rtw_memcpy(pwlanhdr->addr3, ra, ETH_ALEN); /* DA = RA */
9853
9854
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9855
pmlmeext->mgnt_seq++;
9856
set_frame_sub_type(pframe, WIFI_ACTION);
9857
9858
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9859
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9860
9861
/* category, action */
9862
{
9863
u8 category, action;
9864
category = RTW_WLAN_CATEGORY_SPECTRUM_MGMT;
9865
action = RTW_WLAN_ACTION_SPCT_CHL_SWITCH;
9866
9867
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
9868
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
9869
}
9870
9871
pframe = rtw_set_ie_ch_switch(pframe, &(pattrib->pktlen), 0, new_ch, 0);
9872
pframe = rtw_set_ie_secondary_ch_offset(pframe, &(pattrib->pktlen),
9873
hal_ch_offset_to_secondary_ch_offset(ch_offset));
9874
9875
pattrib->last_txcmdsz = pattrib->pktlen;
9876
9877
dump_mgntframe(padapter, pmgntframe);
9878
9879
}
9880
9881
#ifdef CONFIG_IEEE80211W
9882
void issue_action_SA_Query(_adapter *padapter, unsigned char *raddr, unsigned char action, unsigned short tid, u8 key_type)
9883
{
9884
u8 category = RTW_WLAN_CATEGORY_SA_QUERY;
9885
u16 reason_code;
9886
struct xmit_frame *pmgntframe;
9887
struct pkt_attrib *pattrib;
9888
u8 *pframe;
9889
struct rtw_ieee80211_hdr *pwlanhdr;
9890
u16 *fctrl;
9891
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9892
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9893
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
9894
struct sta_info *psta;
9895
struct sta_priv *pstapriv = &padapter->stapriv;
9896
struct registry_priv *pregpriv = &padapter->registrypriv;
9897
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
9898
9899
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
9900
return;
9901
9902
RTW_INFO("%s, %04x\n", __FUNCTION__, tid);
9903
9904
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
9905
if (pmgntframe == NULL) {
9906
RTW_INFO("%s: alloc_mgtxmitframe fail\n", __FUNCTION__);
9907
return;
9908
}
9909
9910
/* update attribute */
9911
pattrib = &pmgntframe->attrib;
9912
update_mgntframe_attrib(padapter, pattrib);
9913
pattrib->key_type = key_type;
9914
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
9915
9916
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
9917
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
9918
9919
fctrl = &(pwlanhdr->frame_ctl);
9920
*(fctrl) = 0;
9921
9922
if (raddr)
9923
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
9924
else
9925
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9926
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
9927
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
9928
9929
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
9930
pmlmeext->mgnt_seq++;
9931
set_frame_sub_type(pframe, WIFI_ACTION);
9932
9933
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
9934
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
9935
9936
pframe = rtw_set_fixed_ie(pframe, 1, &category, &pattrib->pktlen);
9937
pframe = rtw_set_fixed_ie(pframe, 1, &action, &pattrib->pktlen);
9938
9939
switch (action) {
9940
case 0: /* SA Query req */
9941
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&pmlmeext->sa_query_seq, &pattrib->pktlen);
9942
pmlmeext->sa_query_seq++;
9943
/* send sa query request to AP, AP should reply sa query response in 1 second */
9944
if (pattrib->key_type == IEEE80211W_RIGHT_KEY) {
9945
psta = rtw_get_stainfo(pstapriv, pwlanhdr->addr1);
9946
if (psta != NULL) {
9947
/* RTW_INFO("%s, %d, set dot11w_expire_timer\n", __func__, __LINE__); */
9948
_set_timer(&psta->dot11w_expire_timer, 1000);
9949
}
9950
}
9951
break;
9952
9953
case 1: /* SA Query rsp */
9954
tid = cpu_to_le16(tid);
9955
/* RTW_INFO("rtw_set_fixed_ie, %04x\n", tid); */
9956
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)&tid, &pattrib->pktlen);
9957
break;
9958
default:
9959
break;
9960
}
9961
9962
pattrib->last_txcmdsz = pattrib->pktlen;
9963
9964
dump_mgntframe(padapter, pmgntframe);
9965
}
9966
#endif /* CONFIG_IEEE80211W */
9967
9968
/**
9969
* issue_action_ba - internal function to TX Block Ack action frame
9970
* @padapter: the adapter to TX
9971
* @raddr: receiver address
9972
* @action: Block Ack Action
9973
* @tid: tid
9974
* @size: the announced AMPDU buffer size. used by ADDBA_RESP
9975
* @status: status/reason code. used by ADDBA_RESP, DELBA
9976
* @initiator: if we are the initiator of AMPDU association. used by DELBA
9977
* @wait_ack: used xmit ack
9978
*
9979
* Returns:
9980
* _SUCCESS: No xmit ack is used or acked
9981
* _FAIL: not acked when using xmit ack
9982
*/
9983
static int issue_action_ba(_adapter *padapter, unsigned char *raddr, unsigned char action
9984
, u8 tid, u8 size, u16 status, u8 initiator, int wait_ack)
9985
{
9986
int ret = _FAIL;
9987
u8 category = RTW_WLAN_CATEGORY_BACK;
9988
u16 start_seq;
9989
u16 BA_para_set;
9990
u16 BA_timeout_value;
9991
u16 BA_starting_seqctrl;
9992
struct xmit_frame *pmgntframe;
9993
struct pkt_attrib *pattrib;
9994
u8 *pframe;
9995
struct rtw_ieee80211_hdr *pwlanhdr;
9996
u16 *fctrl;
9997
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
9998
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
9999
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10000
struct sta_info *psta;
10001
struct sta_priv *pstapriv = &padapter->stapriv;
10002
struct registry_priv *pregpriv = &padapter->registrypriv;
10003
10004
#ifdef CONFIG_80211N_HT
10005
10006
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10007
goto exit;
10008
10009
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10010
if (pmgntframe == NULL)
10011
goto exit;
10012
10013
/* update attribute */
10014
pattrib = &pmgntframe->attrib;
10015
update_mgntframe_attrib(padapter, pattrib);
10016
10017
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10018
10019
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10020
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10021
10022
fctrl = &(pwlanhdr->frame_ctl);
10023
*(fctrl) = 0;
10024
10025
/* _rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); */
10026
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN);
10027
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10028
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10029
10030
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10031
pmlmeext->mgnt_seq++;
10032
set_frame_sub_type(pframe, WIFI_ACTION);
10033
10034
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10035
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10036
10037
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10038
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10039
10040
if (category == 3) {
10041
switch (action) {
10042
case RTW_WLAN_ACTION_ADDBA_REQ:
10043
do {
10044
pmlmeinfo->dialogToken++;
10045
} while (pmlmeinfo->dialogToken == 0);
10046
pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->dialogToken), &(pattrib->pktlen));
10047
10048
#if defined(CONFIG_RTL8188E) && defined(CONFIG_SDIO_HCI)
10049
BA_para_set = (0x0802 | ((tid & 0xf) << 2)); /* immediate ack & 16 buffer size */
10050
#else
10051
BA_para_set = (0x1002 | ((tid & 0xf) << 2)); /* immediate ack & 64 buffer size */
10052
#endif
10053
10054
#ifdef CONFIG_TX_AMSDU
10055
if (padapter->tx_amsdu >= 1) /* TX AMSDU enabled */
10056
BA_para_set |= BIT(0);
10057
else /* TX AMSDU disabled */
10058
BA_para_set &= ~BIT(0);
10059
#endif
10060
BA_para_set = cpu_to_le16(BA_para_set);
10061
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10062
10063
/* BA_timeout_value = 0xffff; */ /* max: 65535 TUs(~ 65 ms) */
10064
BA_timeout_value = 5000;/* ~ 5ms */
10065
BA_timeout_value = cpu_to_le16(BA_timeout_value);
10066
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_timeout_value)), &(pattrib->pktlen));
10067
10068
/* if ((psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress)) != NULL) */
10069
psta = rtw_get_stainfo(pstapriv, raddr);
10070
if (psta != NULL) {
10071
start_seq = (psta->sta_xmitpriv.txseq_tid[tid & 0x07] & 0xfff) + 1;
10072
10073
RTW_INFO("BA_starting_seqctrl = %d for TID=%d\n", start_seq, tid & 0x07);
10074
10075
psta->BA_starting_seqctrl[tid & 0x07] = start_seq;
10076
10077
BA_starting_seqctrl = start_seq << 4;
10078
}
10079
10080
BA_starting_seqctrl = cpu_to_le16(BA_starting_seqctrl);
10081
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_starting_seqctrl)), &(pattrib->pktlen));
10082
break;
10083
10084
case RTW_WLAN_ACTION_ADDBA_RESP:
10085
pframe = rtw_set_fixed_ie(pframe, 1, &(pmlmeinfo->ADDBA_req.dialog_token), &(pattrib->pktlen));
10086
status = cpu_to_le16(status);
10087
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&status), &(pattrib->pktlen));
10088
10089
BA_para_set = le16_to_cpu(pmlmeinfo->ADDBA_req.BA_para_set);
10090
10091
BA_para_set &= ~IEEE80211_ADDBA_PARAM_TID_MASK;
10092
BA_para_set |= (tid << 2) & IEEE80211_ADDBA_PARAM_TID_MASK;
10093
10094
BA_para_set &= ~RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
10095
BA_para_set |= (size << 6) & RTW_IEEE80211_ADDBA_PARAM_BUF_SIZE_MASK;
10096
10097
if (!padapter->registrypriv.wifi_spec) {
10098
if (pregpriv->rx_ampdu_amsdu == 0) /* disabled */
10099
BA_para_set &= ~BIT(0);
10100
else if (pregpriv->rx_ampdu_amsdu == 1) /* enabled */
10101
BA_para_set |= BIT(0);
10102
}
10103
10104
BA_para_set = cpu_to_le16(BA_para_set);
10105
10106
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10107
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(pmlmeinfo->ADDBA_req.BA_timeout_value)), &(pattrib->pktlen));
10108
break;
10109
10110
case RTW_WLAN_ACTION_DELBA:
10111
BA_para_set = 0;
10112
BA_para_set |= (tid << 12) & IEEE80211_DELBA_PARAM_TID_MASK;
10113
BA_para_set |= (initiator << 11) & IEEE80211_DELBA_PARAM_INITIATOR_MASK;
10114
10115
BA_para_set = cpu_to_le16(BA_para_set);
10116
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(BA_para_set)), &(pattrib->pktlen));
10117
status = cpu_to_le16(status);
10118
pframe = rtw_set_fixed_ie(pframe, 2, (unsigned char *)(&(status)), &(pattrib->pktlen));
10119
break;
10120
default:
10121
break;
10122
}
10123
}
10124
10125
pattrib->last_txcmdsz = pattrib->pktlen;
10126
10127
if (wait_ack)
10128
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10129
else {
10130
dump_mgntframe(padapter, pmgntframe);
10131
ret = _SUCCESS;
10132
}
10133
10134
exit:
10135
#endif /* CONFIG_80211N_HT */
10136
return ret;
10137
}
10138
10139
/**
10140
* issue_addba_req - TX ADDBA_REQ
10141
* @adapter: the adapter to TX
10142
* @ra: receiver address
10143
* @tid: tid
10144
*/
10145
inline void issue_addba_req(_adapter *adapter, unsigned char *ra, u8 tid)
10146
{
10147
issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_REQ
10148
, tid
10149
, 0 /* unused */
10150
, 0 /* unused */
10151
, 0 /* unused */
10152
, _FALSE
10153
);
10154
RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" tid=%u\n"
10155
, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), tid);
10156
10157
}
10158
10159
/**
10160
* issue_addba_rsp - TX ADDBA_RESP
10161
* @adapter: the adapter to TX
10162
* @ra: receiver address
10163
* @tid: tid
10164
* @status: status code
10165
* @size: the announced AMPDU buffer size
10166
*/
10167
inline void issue_addba_rsp(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size)
10168
{
10169
issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10170
, tid
10171
, size
10172
, status
10173
, 0 /* unused */
10174
, _FALSE
10175
);
10176
RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status=%u, tid=%u, size=%u\n"
10177
, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size);
10178
}
10179
10180
/**
10181
* issue_addba_rsp_wait_ack - TX ADDBA_RESP and wait ack
10182
* @adapter: the adapter to TX
10183
* @ra: receiver address
10184
* @tid: tid
10185
* @status: status code
10186
* @size: the announced AMPDU buffer size
10187
* @try_cnt: the maximal TX count to try
10188
* @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10189
* > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10190
*/
10191
inline u8 issue_addba_rsp_wait_ack(_adapter *adapter, unsigned char *ra, u8 tid, u16 status, u8 size, int try_cnt, int wait_ms)
10192
{
10193
int ret = _FAIL;
10194
int i = 0;
10195
systime start = rtw_get_current_time();
10196
10197
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10198
goto exit;
10199
10200
do {
10201
ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_ADDBA_RESP
10202
, tid
10203
, size
10204
, status
10205
, 0 /* unused */
10206
, _TRUE
10207
);
10208
10209
i++;
10210
10211
if (RTW_CANNOT_RUN(adapter))
10212
break;
10213
10214
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10215
rtw_msleep_os(wait_ms);
10216
10217
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10218
10219
if (ret != _FAIL) {
10220
ret = _SUCCESS;
10221
#ifndef DBG_XMIT_ACK
10222
/* goto exit; */
10223
#endif
10224
}
10225
10226
if (try_cnt && wait_ms) {
10227
RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" status:=%u tid=%u size:%u%s, %d/%d in %u ms\n"
10228
, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), status, tid, size
10229
, ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10230
}
10231
10232
exit:
10233
return ret;
10234
}
10235
10236
/**
10237
* issue_del_ba - TX DELBA
10238
* @adapter: the adapter to TX
10239
* @ra: receiver address
10240
* @tid: tid
10241
* @reason: reason code
10242
* @initiator: if we are the initiator of AMPDU association. used by DELBA
10243
*/
10244
inline void issue_del_ba(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator)
10245
{
10246
issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10247
, tid
10248
, 0 /* unused */
10249
, reason
10250
, initiator
10251
, _FALSE
10252
);
10253
RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u\n"
10254
, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator);
10255
}
10256
10257
/**
10258
* issue_del_ba_ex - TX DELBA with xmit ack options
10259
* @adapter: the adapter to TX
10260
* @ra: receiver address
10261
* @tid: tid
10262
* @reason: reason code
10263
* @initiator: if we are the initiator of AMPDU association. used by DELBA
10264
* @try_cnt: the maximal TX count to try
10265
* @wait_ms: == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10266
* > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10267
*/
10268
int issue_del_ba_ex(_adapter *adapter, unsigned char *ra, u8 tid, u16 reason, u8 initiator
10269
, int try_cnt, int wait_ms)
10270
{
10271
int ret = _FAIL;
10272
int i = 0;
10273
systime start = rtw_get_current_time();
10274
10275
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(adapter)))
10276
goto exit;
10277
10278
do {
10279
ret = issue_action_ba(adapter, ra, RTW_WLAN_ACTION_DELBA
10280
, tid
10281
, 0 /* unused */
10282
, reason
10283
, initiator
10284
, wait_ms > 0 ? _TRUE : _FALSE
10285
);
10286
10287
i++;
10288
10289
if (RTW_CANNOT_RUN(adapter))
10290
break;
10291
10292
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10293
rtw_msleep_os(wait_ms);
10294
10295
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10296
10297
if (ret != _FAIL) {
10298
ret = _SUCCESS;
10299
#ifndef DBG_XMIT_ACK
10300
/* goto exit; */
10301
#endif
10302
}
10303
10304
if (try_cnt && wait_ms) {
10305
RTW_INFO(FUNC_ADPT_FMT" ra="MAC_FMT" reason=%u, tid=%u, initiator=%u%s, %d/%d in %u ms\n"
10306
, FUNC_ADPT_ARG(adapter), MAC_ARG(ra), reason, tid, initiator
10307
, ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10308
}
10309
exit:
10310
return ret;
10311
}
10312
10313
void issue_action_BSSCoexistPacket(_adapter *padapter)
10314
{
10315
_irqL irqL;
10316
_list *plist, *phead;
10317
unsigned char category, action;
10318
struct xmit_frame *pmgntframe;
10319
struct pkt_attrib *pattrib;
10320
unsigned char *pframe;
10321
struct rtw_ieee80211_hdr *pwlanhdr;
10322
unsigned short *fctrl;
10323
struct wlan_network *pnetwork = NULL;
10324
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10325
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
10326
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10327
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10328
_queue *queue = &(pmlmepriv->scanned_queue);
10329
u8 InfoContent[16] = {0};
10330
u8 ICS[8][15];
10331
#ifdef CONFIG_80211N_HT
10332
if ((pmlmepriv->num_FortyMHzIntolerant == 0) && (pmlmepriv->num_sta_no_ht == 0))
10333
return;
10334
10335
if (_TRUE == pmlmeinfo->bwmode_updated)
10336
return;
10337
10338
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10339
return;
10340
10341
RTW_INFO("%s\n", __FUNCTION__);
10342
10343
10344
category = RTW_WLAN_CATEGORY_PUBLIC;
10345
action = ACT_PUBLIC_BSSCOEXIST;
10346
10347
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10348
if (pmgntframe == NULL)
10349
return;
10350
10351
/* update attribute */
10352
pattrib = &pmgntframe->attrib;
10353
update_mgntframe_attrib(padapter, pattrib);
10354
10355
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10356
10357
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10358
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10359
10360
fctrl = &(pwlanhdr->frame_ctl);
10361
*(fctrl) = 0;
10362
10363
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10364
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
10365
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN);
10366
10367
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10368
pmlmeext->mgnt_seq++;
10369
set_frame_sub_type(pframe, WIFI_ACTION);
10370
10371
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10372
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10373
10374
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10375
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10376
10377
/* TODO calculate 40Mhz intolerant via ch and ch offset */
10378
/* if (pmlmepriv->num_FortyMHzIntolerant > 0) */
10379
{
10380
u8 iedata = 0;
10381
10382
iedata |= BIT(2);/* 20 MHz BSS Width Request */
10383
pframe = rtw_set_ie(pframe, EID_BSSCoexistence, 1, &iedata, &(pattrib->pktlen));
10384
}
10385
10386
/* */
10387
_rtw_memset(ICS, 0, sizeof(ICS));
10388
if (pmlmepriv->num_sta_no_ht > 0) {
10389
int i;
10390
10391
_enter_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10392
10393
phead = get_list_head(queue);
10394
plist = get_next(phead);
10395
10396
while (1) {
10397
int len;
10398
u8 *p;
10399
WLAN_BSSID_EX *pbss_network;
10400
10401
if (rtw_end_of_queue_search(phead, plist) == _TRUE)
10402
break;
10403
10404
pnetwork = LIST_CONTAINOR(plist, struct wlan_network, list);
10405
10406
plist = get_next(plist);
10407
10408
pbss_network = (WLAN_BSSID_EX *)&pnetwork->network;
10409
10410
p = rtw_get_ie(pbss_network->IEs + _FIXED_IE_LENGTH_, _HT_CAPABILITY_IE_, &len, pbss_network->IELength - _FIXED_IE_LENGTH_);
10411
if ((p == NULL) || (len == 0)) { /* non-HT */
10412
if ((pbss_network->Configuration.DSConfig <= 0) || (pbss_network->Configuration.DSConfig > 14))
10413
continue;
10414
10415
ICS[0][pbss_network->Configuration.DSConfig] = 1;
10416
10417
if (ICS[0][0] == 0)
10418
ICS[0][0] = 1;
10419
}
10420
10421
}
10422
10423
_exit_critical_bh(&(pmlmepriv->scanned_queue.lock), &irqL);
10424
10425
10426
for (i = 0; i < 8; i++) {
10427
if (ICS[i][0] == 1) {
10428
int j, k = 0;
10429
10430
InfoContent[k] = i;
10431
/* SET_BSS_INTOLERANT_ELE_REG_CLASS(InfoContent,i); */
10432
k++;
10433
10434
for (j = 1; j <= 14; j++) {
10435
if (ICS[i][j] == 1) {
10436
if (k < 16) {
10437
InfoContent[k] = j; /* channel number */
10438
/* SET_BSS_INTOLERANT_ELE_CHANNEL(InfoContent+k, j); */
10439
k++;
10440
}
10441
}
10442
}
10443
10444
pframe = rtw_set_ie(pframe, EID_BSSIntolerantChlReport, k, InfoContent, &(pattrib->pktlen));
10445
10446
}
10447
10448
}
10449
10450
10451
}
10452
10453
10454
pattrib->last_txcmdsz = pattrib->pktlen;
10455
10456
dump_mgntframe(padapter, pmgntframe);
10457
#endif /* CONFIG_80211N_HT */
10458
}
10459
10460
/* Spatial Multiplexing Powersave (SMPS) action frame */
10461
int _issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode , u8 wait_ack)
10462
{
10463
10464
int ret = _FAIL;
10465
unsigned char category = RTW_WLAN_CATEGORY_HT;
10466
u8 action = RTW_WLAN_ACTION_HT_SM_PS;
10467
u8 sm_power_control = 0;
10468
struct xmit_frame *pmgntframe;
10469
struct pkt_attrib *pattrib;
10470
unsigned char *pframe;
10471
struct rtw_ieee80211_hdr *pwlanhdr;
10472
unsigned short *fctrl;
10473
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
10474
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
10475
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10476
10477
10478
if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DISABLED) {
10479
sm_power_control = sm_power_control & ~(BIT(0)); /* SM Power Save Enable = 0 SM Power Save Disable */
10480
} else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_STATIC) {
10481
sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable */
10482
sm_power_control = sm_power_control & ~(BIT(1)); /* SM Mode = 0 Static Mode */
10483
} else if (NewMimoPsMode == WLAN_HT_CAP_SM_PS_DYNAMIC) {
10484
sm_power_control = sm_power_control | BIT(0); /* SM Power Save Enable = 1 SM Power Save Enable */
10485
sm_power_control = sm_power_control | BIT(1); /* SM Mode = 1 Dynamic Mode */
10486
} else
10487
return ret;
10488
10489
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10490
return ret;
10491
10492
RTW_INFO("%s, sm_power_control=%u, NewMimoPsMode=%u\n", __FUNCTION__ , sm_power_control , NewMimoPsMode);
10493
10494
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
10495
if (pmgntframe == NULL)
10496
return ret;
10497
10498
/* update attribute */
10499
pattrib = &pmgntframe->attrib;
10500
update_mgntframe_attrib(padapter, pattrib);
10501
10502
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
10503
10504
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
10505
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
10506
10507
fctrl = &(pwlanhdr->frame_ctl);
10508
*(fctrl) = 0;
10509
10510
_rtw_memcpy(pwlanhdr->addr1, raddr, ETH_ALEN); /* RA */
10511
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN); /* TA */
10512
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&(pmlmeinfo->network)), ETH_ALEN); /* DA = RA */
10513
10514
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
10515
pmlmeext->mgnt_seq++;
10516
set_frame_sub_type(pframe, WIFI_ACTION);
10517
10518
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
10519
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
10520
10521
/* category, action */
10522
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
10523
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
10524
10525
pframe = rtw_set_fixed_ie(pframe, 1, &(sm_power_control), &(pattrib->pktlen));
10526
10527
pattrib->last_txcmdsz = pattrib->pktlen;
10528
10529
if (wait_ack)
10530
ret = dump_mgntframe_and_wait_ack(padapter, pmgntframe);
10531
else {
10532
dump_mgntframe(padapter, pmgntframe);
10533
ret = _SUCCESS;
10534
}
10535
10536
if (ret != _SUCCESS)
10537
RTW_INFO("%s, ack to\n", __func__);
10538
10539
return ret;
10540
}
10541
10542
/*
10543
* wait_ms == 0 means that there is no need to wait ack through C2H_CCX_TX_RPT
10544
* wait_ms > 0 means you want to wait ack through C2H_CCX_TX_RPT, and the value of wait_ms means the interval between each TX
10545
* try_cnt means the maximal TX count to try
10546
*/
10547
int issue_action_SM_PS_wait_ack(_adapter *padapter, unsigned char *raddr, u8 NewMimoPsMode, int try_cnt, int wait_ms)
10548
{
10549
int ret = _FAIL;
10550
int i = 0;
10551
systime start = rtw_get_current_time();
10552
10553
if (rtw_rfctl_is_tx_blocked_by_ch_waiting(adapter_to_rfctl(padapter)))
10554
goto exit;
10555
10556
do {
10557
ret = _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , wait_ms > 0 ? _TRUE : _FALSE);
10558
10559
i++;
10560
10561
if (RTW_CANNOT_RUN(padapter))
10562
break;
10563
10564
if (i < try_cnt && wait_ms > 0 && ret == _FAIL)
10565
rtw_msleep_os(wait_ms);
10566
10567
} while ((i < try_cnt) && ((ret == _FAIL) || (wait_ms == 0)));
10568
10569
if (ret != _FAIL) {
10570
ret = _SUCCESS;
10571
#ifndef DBG_XMIT_ACK
10572
goto exit;
10573
#endif
10574
}
10575
10576
if (try_cnt && wait_ms) {
10577
if (raddr)
10578
RTW_INFO(FUNC_ADPT_FMT" to "MAC_FMT", %s , %d/%d in %u ms\n",
10579
FUNC_ADPT_ARG(padapter), MAC_ARG(raddr),
10580
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10581
else
10582
RTW_INFO(FUNC_ADPT_FMT", %s , %d/%d in %u ms\n",
10583
FUNC_ADPT_ARG(padapter),
10584
ret == _SUCCESS ? ", acked" : "", i, try_cnt, rtw_get_passing_time_ms(start));
10585
}
10586
exit:
10587
10588
return ret;
10589
}
10590
10591
int issue_action_SM_PS(_adapter *padapter , unsigned char *raddr , u8 NewMimoPsMode)
10592
{
10593
RTW_INFO("%s to "MAC_FMT"\n", __func__, MAC_ARG(raddr));
10594
return _issue_action_SM_PS(padapter, raddr, NewMimoPsMode , _FALSE);
10595
}
10596
10597
/**
10598
* _send_delba_sta_tid - Cancel the AMPDU association for the specific @sta, @tid
10599
* @adapter: the adapter to which @sta belongs
10600
* @initiator: if we are the initiator of AMPDU association
10601
* @sta: the sta to be checked
10602
* @tid: the tid to be checked
10603
* @force: cancel and send DELBA even when no AMPDU association is setup
10604
* @wait_ack: send delba with xmit ack (valid when initiator == 0)
10605
*
10606
* Returns:
10607
* _FAIL if sta is NULL
10608
* when initiator is 1, always _SUCCESS
10609
* when initiator is 0, _SUCCESS if DELBA is acked
10610
*/
10611
static unsigned int _send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10612
, u8 force, int wait_ack)
10613
{
10614
int ret = _SUCCESS;
10615
10616
if (sta == NULL) {
10617
ret = _FAIL;
10618
goto exit;
10619
}
10620
10621
if (initiator == 0) {
10622
/* recipient */
10623
if (force || sta->recvreorder_ctrl[tid].enable == _TRUE) {
10624
u8 ampdu_size_bak = sta->recvreorder_ctrl[tid].ampdu_size;
10625
10626
sta->recvreorder_ctrl[tid].enable = _FALSE;
10627
sta->recvreorder_ctrl[tid].ampdu_size = RX_AMPDU_SIZE_INVALID;
10628
10629
if (rtw_del_rx_ampdu_test_trigger_no_tx_fail())
10630
ret = _FAIL;
10631
else if (wait_ack)
10632
ret = issue_del_ba_ex(adapter, sta->cmn.mac_addr, tid, 37, initiator, 3, 1);
10633
else
10634
issue_del_ba(adapter, sta->cmn.mac_addr, tid, 37, initiator);
10635
10636
if (ret == _FAIL && sta->recvreorder_ctrl[tid].enable == _FALSE)
10637
sta->recvreorder_ctrl[tid].ampdu_size = ampdu_size_bak;
10638
}
10639
} else if (initiator == 1) {
10640
/* originator */
10641
#ifdef CONFIG_80211N_HT
10642
if (force || sta->htpriv.agg_enable_bitmap & BIT(tid)) {
10643
sta->htpriv.agg_enable_bitmap &= ~BIT(tid);
10644
sta->htpriv.candidate_tid_bitmap &= ~BIT(tid);
10645
issue_del_ba(adapter, sta->cmn.mac_addr, tid, 37, initiator);
10646
}
10647
#endif
10648
}
10649
10650
exit:
10651
return ret;
10652
}
10653
10654
inline unsigned int send_delba_sta_tid(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10655
, u8 force)
10656
{
10657
return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 0);
10658
}
10659
10660
inline unsigned int send_delba_sta_tid_wait_ack(_adapter *adapter, u8 initiator, struct sta_info *sta, u8 tid
10661
, u8 force)
10662
{
10663
return _send_delba_sta_tid(adapter, initiator, sta, tid, force, 1);
10664
}
10665
10666
unsigned int send_delba(_adapter *padapter, u8 initiator, u8 *addr)
10667
{
10668
struct sta_priv *pstapriv = &padapter->stapriv;
10669
struct sta_info *psta = NULL;
10670
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10671
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10672
u16 tid;
10673
10674
if ((pmlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
10675
if (!(pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS))
10676
return _SUCCESS;
10677
10678
psta = rtw_get_stainfo(pstapriv, addr);
10679
if (psta == NULL)
10680
return _SUCCESS;
10681
10682
#if 0
10683
RTW_INFO("%s:%s\n", __func__, (initiator == 0) ? "RX_DIR" : "TX_DIR");
10684
if (initiator == 1) /* originator */
10685
RTW_INFO("tx agg_enable_bitmap(0x%08x)\n", psta->htpriv.agg_enable_bitmap);
10686
#endif
10687
10688
for (tid = 0; tid < TID_NUM; tid++)
10689
send_delba_sta_tid(padapter, initiator, psta, tid, 0);
10690
10691
return _SUCCESS;
10692
}
10693
10694
unsigned int send_beacon(_adapter *padapter)
10695
{
10696
#if defined(CONFIG_PCI_HCI) && !defined(CONFIG_PCI_BCN_POLLING)
10697
#ifdef CONFIG_FW_HANDLE_TXBCN
10698
u8 vap_id = padapter->vap_id;
10699
10700
/* bypass TX BCN because vap_id is invalid*/
10701
if (vap_id == CONFIG_LIMITED_AP_NUM)
10702
return _SUCCESS;
10703
#endif
10704
10705
/* bypass TX BCN queue because op ch is switching/waiting */
10706
if (check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
10707
|| IS_CH_WAITING(adapter_to_rfctl(padapter))
10708
)
10709
return _SUCCESS;
10710
10711
/* RTW_INFO("%s\n", __FUNCTION__); */
10712
10713
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10714
10715
/* 8192EE Port select for Beacon DL */
10716
rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10717
#ifdef CONFIG_FW_HANDLE_TXBCN
10718
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
10719
#endif
10720
10721
issue_beacon(padapter, 0);
10722
10723
#ifdef CONFIG_FW_HANDLE_TXBCN
10724
vap_id = 0xFF;
10725
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
10726
#endif
10727
10728
#ifdef RTL8814AE_SW_BCN
10729
if (GET_HAL_DATA(padapter)->bCorrectBCN != 0)
10730
RTW_INFO("%s, line%d, Warnning, pHalData->bCorrectBCN != 0\n", __func__, __LINE__);
10731
GET_HAL_DATA(padapter)->bCorrectBCN = 1;
10732
#endif
10733
10734
return _SUCCESS;
10735
#endif
10736
10737
/* CONFIG_PCI_BCN_POLLING is for pci interface beacon polling mode */
10738
#if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)|| defined(CONFIG_PCI_BCN_POLLING)
10739
u8 bxmitok = _FALSE;
10740
int issue = 0;
10741
int poll = 0;
10742
systime start = rtw_get_current_time();
10743
#ifdef CONFIG_FW_HANDLE_TXBCN
10744
u8 vap_id = padapter->vap_id;
10745
10746
/* bypass TX BCN because vap_id is invalid*/
10747
if (vap_id == CONFIG_LIMITED_AP_NUM)
10748
return _SUCCESS;
10749
#endif
10750
10751
/* bypass TX BCN queue because op ch is switching/waiting */
10752
if (check_fwstate(&padapter->mlmepriv, WIFI_OP_CH_SWITCHING)
10753
|| IS_CH_WAITING(adapter_to_rfctl(padapter))
10754
)
10755
return _SUCCESS;
10756
10757
#if defined(CONFIG_USB_HCI)
10758
#if defined(CONFIG_RTL8812A)
10759
if (IS_FULL_SPEED_USB(padapter)) {
10760
issue_beacon(padapter, 300);
10761
bxmitok = _TRUE;
10762
} else
10763
#endif
10764
#endif
10765
{
10766
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);
10767
rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
10768
#ifdef CONFIG_FW_HANDLE_TXBCN
10769
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
10770
#endif
10771
do {
10772
#if defined(CONFIG_PCI_BCN_POLLING)
10773
issue_beacon(padapter, 0);
10774
#else
10775
issue_beacon(padapter, 100);
10776
#endif
10777
issue++;
10778
do {
10779
#if defined(CONFIG_PCI_BCN_POLLING)
10780
rtw_msleep_os(1);
10781
#else
10782
rtw_yield_os();
10783
#endif
10784
rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bxmitok));
10785
poll++;
10786
} while ((poll % 10) != 0 && _FALSE == bxmitok && !RTW_CANNOT_RUN(padapter));
10787
#if defined(CONFIG_PCI_BCN_POLLING)
10788
rtw_hal_unmap_beacon_icf(padapter);
10789
#endif
10790
} while (bxmitok == _FALSE && (issue < 100) && !RTW_CANNOT_RUN(padapter));
10791
#ifdef CONFIG_FW_HANDLE_TXBCN
10792
vap_id = 0xFF;
10793
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_HEAD_SEL, &vap_id);
10794
#endif
10795
}
10796
if (RTW_CANNOT_RUN(padapter))
10797
return _FAIL;
10798
10799
10800
if (_FALSE == bxmitok) {
10801
RTW_INFO("%s fail! %u ms\n", __FUNCTION__, rtw_get_passing_time_ms(start));
10802
#ifdef CONFIG_BCN_RECOVERY
10803
GET_HAL_DATA(padapter)->issue_bcn_fail++;
10804
#endif /*CONFIG_BCN_RECOVERY*/
10805
return _FAIL;
10806
} else {
10807
u32 passing_time = rtw_get_passing_time_ms(start);
10808
10809
if (passing_time > 100 || issue > 3)
10810
RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10811
else if (0)
10812
RTW_INFO("%s success, issue:%d, poll:%d, %u ms\n", __FUNCTION__, issue, poll, rtw_get_passing_time_ms(start));
10813
10814
#ifdef CONFIG_FW_CORRECT_BCN
10815
rtw_hal_fw_correct_bcn(padapter);
10816
#endif
10817
return _SUCCESS;
10818
}
10819
10820
#endif /*defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)*/
10821
10822
}
10823
10824
/****************************************************************************
10825
10826
Following are some utitity fuctions for WiFi MLME
10827
10828
*****************************************************************************/
10829
10830
BOOLEAN IsLegal5GChannel(
10831
PADAPTER Adapter,
10832
u8 channel)
10833
{
10834
10835
int i = 0;
10836
u8 Channel_5G[45] = {36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
10837
60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
10838
124, 126, 128, 130, 132, 134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
10839
161, 163, 165
10840
};
10841
for (i = 0; i < sizeof(Channel_5G); i++)
10842
if (channel == Channel_5G[i])
10843
return _TRUE;
10844
return _FALSE;
10845
}
10846
10847
/* collect bss info from Beacon and Probe request/response frames. */
10848
u8 collect_bss_info(_adapter *padapter, union recv_frame *precv_frame, WLAN_BSSID_EX *bssid)
10849
{
10850
int i;
10851
sint len;
10852
u8 *p;
10853
u8 rf_path;
10854
u16 val16, subtype;
10855
u8 *pframe = precv_frame->u.hdr.rx_data;
10856
u32 packet_len = precv_frame->u.hdr.len;
10857
u8 ie_offset;
10858
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
10859
struct registry_priv *pregistrypriv = &padapter->registrypriv;
10860
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
10861
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
10862
10863
10864
len = packet_len - sizeof(struct rtw_ieee80211_hdr_3addr);
10865
10866
if (len > MAX_IE_SZ) {
10867
/* RTW_INFO("IE too long for survey event\n"); */
10868
return _FAIL;
10869
}
10870
10871
_rtw_memset(bssid, 0, sizeof(WLAN_BSSID_EX));
10872
10873
subtype = get_frame_sub_type(pframe);
10874
10875
if (subtype == WIFI_BEACON) {
10876
bssid->Reserved[0] = BSS_TYPE_BCN;
10877
ie_offset = _BEACON_IE_OFFSET_;
10878
} else {
10879
/* FIXME : more type */
10880
if (subtype == WIFI_PROBERSP) {
10881
ie_offset = _PROBERSP_IE_OFFSET_;
10882
bssid->Reserved[0] = BSS_TYPE_PROB_RSP;
10883
} else if (subtype == WIFI_PROBEREQ) {
10884
ie_offset = _PROBEREQ_IE_OFFSET_;
10885
bssid->Reserved[0] = BSS_TYPE_PROB_REQ;
10886
} else {
10887
bssid->Reserved[0] = BSS_TYPE_UNDEF;
10888
ie_offset = _FIXED_IE_LENGTH_;
10889
}
10890
}
10891
10892
bssid->Length = sizeof(WLAN_BSSID_EX) - MAX_IE_SZ + len;
10893
10894
/* below is to copy the information element */
10895
bssid->IELength = len;
10896
_rtw_memcpy(bssid->IEs, (pframe + sizeof(struct rtw_ieee80211_hdr_3addr)), bssid->IELength);
10897
10898
/* get the signal strength */
10899
/* bssid->Rssi = precv_frame->u.hdr.attrib.SignalStrength; */ /* 0-100 index. */
10900
bssid->Rssi = precv_frame->u.hdr.attrib.phy_info.recv_signal_power; /* in dBM.raw data */
10901
bssid->PhyInfo.SignalQuality = precv_frame->u.hdr.attrib.phy_info.signal_quality;/* in percentage */
10902
bssid->PhyInfo.SignalStrength = precv_frame->u.hdr.attrib.phy_info.signal_strength;/* in percentage */
10903
10904
/* get rx_snr */
10905
if (precv_frame->u.hdr.attrib.data_rate >= DESC_RATE11M) {
10906
bssid->PhyInfo.is_cck_rate = 0;
10907
for (rf_path = 0; rf_path < pHalData->NumTotalRFPath; rf_path++)
10908
bssid->PhyInfo.rx_snr[rf_path] =
10909
precv_frame->u.hdr.attrib.phy_info.rx_snr[rf_path];
10910
} else
10911
bssid->PhyInfo.is_cck_rate = 1;
10912
10913
#ifdef CONFIG_ANTENNA_DIVERSITY
10914
rtw_hal_get_odm_var(padapter, HAL_ODM_ANTDIV_SELECT, &(bssid->PhyInfo.Optimum_antenna), NULL);
10915
#endif
10916
10917
/* checking SSID */
10918
p = rtw_get_ie(bssid->IEs + ie_offset, _SSID_IE_, &len, bssid->IELength - ie_offset);
10919
if (p == NULL) {
10920
RTW_INFO("marc: cannot find SSID for survey event\n");
10921
return _FAIL;
10922
}
10923
10924
if (*(p + 1)) {
10925
if (len > NDIS_802_11_LENGTH_SSID) {
10926
RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10927
return _FAIL;
10928
}
10929
_rtw_memcpy(bssid->Ssid.Ssid, (p + 2), *(p + 1));
10930
bssid->Ssid.SsidLength = *(p + 1);
10931
} else
10932
bssid->Ssid.SsidLength = 0;
10933
10934
_rtw_memset(bssid->SupportedRates, 0, NDIS_802_11_LENGTH_RATES_EX);
10935
10936
/* checking rate info... */
10937
i = 0;
10938
p = rtw_get_ie(bssid->IEs + ie_offset, _SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10939
if (p != NULL) {
10940
if (len > NDIS_802_11_LENGTH_RATES_EX) {
10941
RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10942
return _FAIL;
10943
}
10944
if (rtw_validate_value(_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) {
10945
rtw_absorb_ssid_ifneed(padapter, bssid, pframe);
10946
RTW_DBG_DUMP("Invalidated Support Rate IE --", p, len+2);
10947
return _FAIL;
10948
}
10949
_rtw_memcpy(bssid->SupportedRates, (p + 2), len);
10950
i = len;
10951
}
10952
10953
p = rtw_get_ie(bssid->IEs + ie_offset, _EXT_SUPPORTEDRATES_IE_, &len, bssid->IELength - ie_offset);
10954
if (p != NULL) {
10955
if (len > (NDIS_802_11_LENGTH_RATES_EX - i)) {
10956
RTW_INFO("%s()-%d: IE too long (%d) for survey event\n", __FUNCTION__, __LINE__, len);
10957
return _FAIL;
10958
}
10959
if (rtw_validate_value(_EXT_SUPPORTEDRATES_IE_, p+2, len) == _FALSE) {
10960
rtw_absorb_ssid_ifneed(padapter, bssid, pframe);
10961
RTW_DBG_DUMP("Invalidated EXT Support Rate IE --", p, len+2);
10962
return _FAIL;
10963
}
10964
_rtw_memcpy(bssid->SupportedRates + i, (p + 2), len);
10965
}
10966
10967
#ifdef CONFIG_P2P
10968
if (subtype == WIFI_PROBEREQ) {
10969
u8 *p2p_ie;
10970
u32 p2p_ielen;
10971
/* Set Listion Channel */
10972
p2p_ie = rtw_get_p2p_ie(bssid->IEs, bssid->IELength, NULL, &p2p_ielen);
10973
if (p2p_ie) {
10974
u32 attr_contentlen = 0;
10975
u8 listen_ch[5] = { 0x00 };
10976
10977
rtw_get_p2p_attr_content(p2p_ie, p2p_ielen, P2P_ATTR_LISTEN_CH, listen_ch, &attr_contentlen);
10978
bssid->Configuration.DSConfig = listen_ch[4];
10979
} else {
10980
/* use current channel */
10981
bssid->Configuration.DSConfig = padapter->mlmeextpriv.cur_channel;
10982
RTW_INFO("%s()-%d: Cannot get p2p_ie. set DSconfig to op_ch(%d)\n", __FUNCTION__, __LINE__, bssid->Configuration.DSConfig);
10983
}
10984
10985
/* FIXME */
10986
bssid->InfrastructureMode = Ndis802_11Infrastructure;
10987
_rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
10988
bssid->Privacy = 1;
10989
return _SUCCESS;
10990
}
10991
#endif /* CONFIG_P2P */
10992
10993
if (bssid->IELength < 12)
10994
return _FAIL;
10995
10996
/* Checking for DSConfig */
10997
p = rtw_get_ie(bssid->IEs + ie_offset, _DSSET_IE_, &len, bssid->IELength - ie_offset);
10998
10999
bssid->Configuration.DSConfig = 0;
11000
bssid->Configuration.Length = 0;
11001
11002
if (p)
11003
bssid->Configuration.DSConfig = *(p + 2);
11004
else {
11005
/* In 5G, some ap do not have DSSET IE */
11006
/* checking HT info for channel */
11007
p = rtw_get_ie(bssid->IEs + ie_offset, _HT_ADD_INFO_IE_, &len, bssid->IELength - ie_offset);
11008
if (p) {
11009
struct HT_info_element *HT_info = (struct HT_info_element *)(p + 2);
11010
bssid->Configuration.DSConfig = HT_info->primary_channel;
11011
} else {
11012
/* use current channel */
11013
bssid->Configuration.DSConfig = rtw_get_oper_ch(padapter);
11014
}
11015
}
11016
11017
_rtw_memcpy(&bssid->Configuration.BeaconPeriod, rtw_get_beacon_interval_from_ie(bssid->IEs), 2);
11018
bssid->Configuration.BeaconPeriod = le32_to_cpu(bssid->Configuration.BeaconPeriod);
11019
11020
val16 = rtw_get_capability((WLAN_BSSID_EX *)bssid);
11021
11022
if ((val16 & 0x03) == cap_ESS) {
11023
bssid->InfrastructureMode = Ndis802_11Infrastructure;
11024
_rtw_memcpy(bssid->MacAddress, get_addr2_ptr(pframe), ETH_ALEN);
11025
} else if ((val16 & 0x03) == cap_IBSS){
11026
bssid->InfrastructureMode = Ndis802_11IBSS;
11027
_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11028
} else if ((val16 & 0x03) == 0x00){
11029
u8 *mesh_id_ie, *mesh_conf_ie;
11030
sint mesh_id_ie_len, mesh_conf_ie_len;
11031
11032
mesh_id_ie = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_MESH_ID, &mesh_id_ie_len, bssid->IELength - ie_offset);
11033
mesh_conf_ie = rtw_get_ie(bssid->IEs + ie_offset, WLAN_EID_MESH_CONFIG, &mesh_conf_ie_len, bssid->IELength - ie_offset);
11034
if (mesh_id_ie || mesh_conf_ie) {
11035
if (!mesh_id_ie) {
11036
RTW_INFO("cannot find Mesh ID for survey event\n");
11037
return _FAIL;
11038
}
11039
if (mesh_id_ie_len) {
11040
if (mesh_id_ie_len > NDIS_802_11_LENGTH_SSID) {
11041
RTW_INFO("Mesh ID too long (%d) for survey event\n", mesh_id_ie_len);
11042
return _FAIL;
11043
}
11044
_rtw_memcpy(bssid->mesh_id.Ssid, (mesh_id_ie + 2), mesh_id_ie_len);
11045
bssid->mesh_id.SsidLength = mesh_id_ie_len;
11046
} else
11047
bssid->mesh_id.SsidLength = 0;
11048
11049
if (!mesh_conf_ie) {
11050
RTW_INFO("cannot find Mesh config for survey event\n");
11051
return _FAIL;
11052
}
11053
if (mesh_conf_ie_len != 7) {
11054
RTW_INFO("invalid Mesh conf IE len (%d) for survey event\n", mesh_conf_ie_len);
11055
return _FAIL;
11056
}
11057
11058
bssid->InfrastructureMode = Ndis802_11_mesh;
11059
_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11060
} else {
11061
/* default cases */
11062
bssid->InfrastructureMode = Ndis802_11IBSS;
11063
_rtw_memcpy(bssid->MacAddress, GetAddr3Ptr(pframe), ETH_ALEN);
11064
}
11065
}
11066
11067
if (val16 & BIT(4))
11068
bssid->Privacy = 1;
11069
else
11070
bssid->Privacy = 0;
11071
11072
bssid->Configuration.ATIMWindow = 0;
11073
11074
/* 20/40 BSS Coexistence check */
11075
if ((pregistrypriv->wifi_spec == 1) && (_FALSE == pmlmeinfo->bwmode_updated)) {
11076
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
11077
#ifdef CONFIG_80211N_HT
11078
p = rtw_get_ie(bssid->IEs + ie_offset, _HT_CAPABILITY_IE_, &len, bssid->IELength - ie_offset);
11079
if (p && len > 0) {
11080
struct HT_caps_element *pHT_caps;
11081
pHT_caps = (struct HT_caps_element *)(p + 2);
11082
11083
if (pHT_caps->u.HT_cap_element.HT_caps_info & BIT(14))
11084
pmlmepriv->num_FortyMHzIntolerant++;
11085
} else
11086
pmlmepriv->num_sta_no_ht++;
11087
#endif /* CONFIG_80211N_HT */
11088
11089
}
11090
11091
#if defined(DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) & 1
11092
if (strcmp(bssid->Ssid.Ssid, DBG_RX_SIGNAL_DISPLAY_SSID_MONITORED) == 0) {
11093
RTW_INFO("Receiving %s("MAC_FMT", DSConfig:%u) from ch%u with ss:%3u, sq:%3u, RawRSSI:%3ld\n"
11094
, bssid->Ssid.Ssid, MAC_ARG(bssid->MacAddress), bssid->Configuration.DSConfig
11095
, rtw_get_oper_ch(padapter)
11096
, bssid->PhyInfo.SignalStrength, bssid->PhyInfo.SignalQuality, bssid->Rssi
11097
);
11098
}
11099
#endif
11100
11101
/* mark bss info receving from nearby channel as SignalQuality 101 */
11102
if (bssid->Configuration.DSConfig != rtw_get_oper_ch(padapter))
11103
bssid->PhyInfo.SignalQuality = 101;
11104
11105
#ifdef CONFIG_RTW_80211K
11106
p = rtw_get_ie(bssid->IEs + ie_offset, _EID_RRM_EN_CAP_IE_, &len, bssid->IELength - ie_offset);
11107
if (p)
11108
_rtw_memcpy(bssid->PhyInfo.rm_en_cap, (p + 2), *(p + 1));
11109
11110
/* save freerun counter */
11111
bssid->PhyInfo.free_cnt = precv_frame->u.hdr.attrib.free_cnt;
11112
#endif
11113
return _SUCCESS;
11114
}
11115
11116
void start_create_ibss(_adapter *padapter)
11117
{
11118
unsigned short caps;
11119
u8 val8;
11120
u8 join_type;
11121
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11122
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11123
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11124
u8 doiqk = _FALSE;
11125
pmlmeext->cur_channel = (u8)pnetwork->Configuration.DSConfig;
11126
pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
11127
11128
/* update wireless mode */
11129
update_wireless_mode(padapter);
11130
11131
/* udpate capability */
11132
caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
11133
update_capinfo(padapter, caps);
11134
if (caps & cap_IBSS) { /* adhoc master */
11135
/* set_opmode_cmd(padapter, adhoc); */ /* removed */
11136
11137
val8 = 0xcf;
11138
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11139
11140
doiqk = _TRUE;
11141
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
11142
11143
/* switch channel */
11144
set_channel_bwmode(padapter, pmlmeext->cur_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
11145
11146
doiqk = _FALSE;
11147
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
11148
11149
beacon_timing_control(padapter);
11150
11151
/* set msr to WIFI_FW_ADHOC_STATE */
11152
pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11153
Set_MSR(padapter, (pmlmeinfo->state & 0x3));
11154
11155
/* issue beacon */
11156
if (send_beacon(padapter) == _FAIL) {
11157
11158
report_join_res(padapter, -1, WLAN_STATUS_UNSPECIFIED_FAILURE);
11159
pmlmeinfo->state = WIFI_FW_NULL_STATE;
11160
} else {
11161
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, padapter->registrypriv.dev_network.MacAddress);
11162
rtw_hal_rcr_set_chk_bssid(padapter, MLME_ADHOC_STARTED);
11163
join_type = 0;
11164
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
11165
11166
report_join_res(padapter, 1, WLAN_STATUS_SUCCESS);
11167
pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
11168
rtw_indicate_connect(padapter);
11169
}
11170
} else {
11171
RTW_INFO("start_create_ibss, invalid cap:%x\n", caps);
11172
return;
11173
}
11174
/* update bc/mc sta_info */
11175
update_bmc_sta(padapter);
11176
11177
}
11178
11179
void start_clnt_join(_adapter *padapter)
11180
{
11181
unsigned short caps;
11182
u8 val8;
11183
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11184
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11185
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
11186
int beacon_timeout;
11187
u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
11188
11189
/* update wireless mode */
11190
update_wireless_mode(padapter);
11191
11192
/* udpate capability */
11193
caps = rtw_get_capability((WLAN_BSSID_EX *)pnetwork);
11194
update_capinfo(padapter, caps);
11195
11196
/* check if sta is ASIX peer and fix IOT issue if it is. */
11197
if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
11198
u8 iot_flag = _TRUE;
11199
rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
11200
}
11201
11202
if (caps & cap_ESS) {
11203
Set_MSR(padapter, WIFI_FW_STATION_STATE);
11204
11205
val8 = (pmlmeinfo->auth_algo == dot11AuthAlgrthm_8021X) ? 0xcc : 0xcf;
11206
11207
#ifdef CONFIG_WAPI_SUPPORT
11208
if (padapter->wapiInfo.bWapiEnable && pmlmeinfo->auth_algo == dot11AuthAlgrthm_WAPI) {
11209
/* Disable TxUseDefaultKey, RxUseDefaultKey, RxBroadcastUseDefaultKey. */
11210
val8 = 0x4c;
11211
}
11212
#endif
11213
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11214
11215
#ifdef CONFIG_DEAUTH_BEFORE_CONNECT
11216
/* Because of AP's not receiving deauth before */
11217
/* AP may: 1)not response auth or 2)deauth us after link is complete */
11218
/* issue deauth before issuing auth to deal with the situation */
11219
11220
/* Commented by Albert 2012/07/21 */
11221
/* For the Win8 P2P connection, it will be hard to have a successful connection if this Wi-Fi doesn't connect to it. */
11222
{
11223
#ifdef CONFIG_P2P
11224
_queue *queue = &(padapter->mlmepriv.scanned_queue);
11225
_list *head = get_list_head(queue);
11226
_list *pos = get_next(head);
11227
struct wlan_network *scanned = NULL;
11228
u8 ie_offset = 0;
11229
_irqL irqL;
11230
bool has_p2p_ie = _FALSE;
11231
11232
_enter_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11233
11234
for (pos = get_next(head); !rtw_end_of_queue_search(head, pos); pos = get_next(pos)) {
11235
11236
scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
11237
11238
if (_rtw_memcmp(&(scanned->network.Ssid), &(pnetwork->Ssid), sizeof(NDIS_802_11_SSID)) == _TRUE
11239
&& _rtw_memcmp(scanned->network.MacAddress, pnetwork->MacAddress, sizeof(NDIS_802_11_MAC_ADDRESS)) == _TRUE
11240
) {
11241
ie_offset = (scanned->network.Reserved[0] == BSS_TYPE_PROB_REQ ? 0 : 12);
11242
if (rtw_get_p2p_ie(scanned->network.IEs + ie_offset, scanned->network.IELength - ie_offset, NULL, NULL))
11243
has_p2p_ie = _TRUE;
11244
break;
11245
}
11246
}
11247
11248
_exit_critical_bh(&(padapter->mlmepriv.scanned_queue.lock), &irqL);
11249
11250
if (scanned == NULL || rtw_end_of_queue_search(head, pos) || has_p2p_ie == _FALSE)
11251
#endif /* CONFIG_P2P */
11252
/* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
11253
issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
11254
}
11255
#endif /* CONFIG_DEAUTH_BEFORE_CONNECT */
11256
11257
/* here wait for receiving the beacon to start auth */
11258
/* and enable a timer */
11259
beacon_timeout = decide_wait_for_beacon_timeout(pmlmeinfo->bcn_interval);
11260
set_link_timer(pmlmeext, beacon_timeout);
11261
_set_timer(&padapter->mlmepriv.assoc_timer,
11262
(REAUTH_TO * REAUTH_LIMIT) + (REASSOC_TO * REASSOC_LIMIT) + beacon_timeout);
11263
11264
#ifdef CONFIG_RTW_80211R
11265
if (rtw_ft_roam(padapter)) {
11266
rtw_ft_start_clnt_join(padapter);
11267
} else
11268
#endif
11269
{
11270
rtw_sta_linking_test_set_start();
11271
pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
11272
}
11273
} else if (caps & cap_IBSS) { /* adhoc client */
11274
Set_MSR(padapter, WIFI_FW_ADHOC_STATE);
11275
11276
val8 = 0xcf;
11277
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, (u8 *)(&val8));
11278
11279
beacon_timing_control(padapter);
11280
11281
pmlmeinfo->state = WIFI_FW_ADHOC_STATE;
11282
11283
report_join_res(padapter, 1, WLAN_STATUS_SUCCESS);
11284
} else {
11285
/* RTW_INFO("marc: invalid cap:%x\n", caps); */
11286
return;
11287
}
11288
11289
}
11290
11291
void start_clnt_auth(_adapter *padapter)
11292
{
11293
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11294
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11295
11296
_cancel_timer_ex(&pmlmeext->link_timer);
11297
11298
pmlmeinfo->state &= (~WIFI_FW_AUTH_NULL);
11299
pmlmeinfo->state |= WIFI_FW_AUTH_STATE;
11300
11301
pmlmeinfo->auth_seq = 1;
11302
pmlmeinfo->reauth_count = 0;
11303
pmlmeinfo->reassoc_count = 0;
11304
pmlmeinfo->link_count = 0;
11305
pmlmeext->retry = 0;
11306
11307
#ifdef CONFIG_RTW_80211R
11308
if (rtw_ft_roam(padapter)) {
11309
rtw_ft_set_status(padapter, RTW_FT_AUTHENTICATING_STA);
11310
RTW_PRINT("start ft auth\n");
11311
} else
11312
#endif
11313
RTW_PRINT("start auth\n");
11314
11315
#ifdef CONFIG_IOCTL_CFG80211
11316
if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE)) {
11317
if (rtw_cached_pmkid(padapter, get_my_bssid(&pmlmeinfo->network)) != -1) {
11318
RTW_INFO("SAE: PMKSA cache entry found\n");
11319
padapter->securitypriv.auth_alg = WLAN_AUTH_OPEN;
11320
goto no_external_auth;
11321
}
11322
11323
RTW_PRINT("SAE: start external auth\n");
11324
rtw_cfg80211_external_auth_request(padapter, NULL);
11325
return;
11326
}
11327
no_external_auth:
11328
#endif /* CONFIG_IOCTL_CFG80211 */
11329
11330
issue_auth(padapter, NULL, 0);
11331
11332
set_link_timer(pmlmeext, REAUTH_TO);
11333
11334
}
11335
11336
11337
void start_clnt_assoc(_adapter *padapter)
11338
{
11339
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11340
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11341
11342
_cancel_timer_ex(&pmlmeext->link_timer);
11343
11344
pmlmeinfo->state &= (~(WIFI_FW_AUTH_NULL | WIFI_FW_AUTH_STATE));
11345
pmlmeinfo->state |= (WIFI_FW_AUTH_SUCCESS | WIFI_FW_ASSOC_STATE);
11346
11347
#ifdef CONFIG_RTW_80211R
11348
if (rtw_ft_roam(padapter))
11349
issue_reassocreq(padapter);
11350
else
11351
#endif
11352
issue_assocreq(padapter);
11353
11354
set_link_timer(pmlmeext, REASSOC_TO);
11355
}
11356
11357
unsigned int receive_disconnect(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, u8 locally_generated)
11358
{
11359
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11360
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11361
11362
if (!(_rtw_memcmp(MacAddr, get_my_bssid(&pmlmeinfo->network), ETH_ALEN)))
11363
return _SUCCESS;
11364
11365
RTW_INFO("%s\n", __FUNCTION__);
11366
11367
#ifdef CONFIG_RTW_REPEATER_SON
11368
rtw_rson_do_disconnect(padapter);
11369
#endif
11370
if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
11371
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
11372
if (report_del_sta_event(padapter, MacAddr, reason, _TRUE, locally_generated) != _FAIL)
11373
pmlmeinfo->state = WIFI_FW_NULL_STATE;
11374
} else if (pmlmeinfo->state & WIFI_FW_LINKING_STATE) {
11375
if (report_join_res(padapter, -2, reason) != _FAIL)
11376
pmlmeinfo->state = WIFI_FW_NULL_STATE;
11377
} else
11378
RTW_INFO(FUNC_ADPT_FMT" - End to Disconnect\n", FUNC_ADPT_ARG(padapter));
11379
#ifdef CONFIG_RTW_80211R
11380
rtw_ft_roam_status_reset(padapter);
11381
#endif
11382
#ifdef CONFIG_RTW_WNM
11383
rtw_wnm_reset_btm_state(padapter);
11384
#endif
11385
}
11386
11387
return _SUCCESS;
11388
}
11389
11390
#ifdef CONFIG_80211D
11391
static void process_80211d(PADAPTER padapter, WLAN_BSSID_EX *bssid)
11392
{
11393
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
11394
struct registry_priv *pregistrypriv;
11395
struct mlme_ext_priv *pmlmeext;
11396
RT_CHANNEL_INFO *chplan_new;
11397
u8 channel;
11398
u8 i;
11399
11400
11401
pregistrypriv = &padapter->registrypriv;
11402
pmlmeext = &padapter->mlmeextpriv;
11403
11404
/* Adjust channel plan by AP Country IE */
11405
if (pregistrypriv->enable80211d
11406
&& (!pmlmeext->update_channel_plan_by_ap_done)) {
11407
u8 *ie, *p;
11408
u32 len;
11409
RT_CHANNEL_PLAN chplan_ap;
11410
RT_CHANNEL_INFO *chplan_sta = NULL;
11411
u8 country[4];
11412
u8 fcn; /* first channel number */
11413
u8 noc; /* number of channel */
11414
u8 j, k;
11415
11416
ie = rtw_get_ie(bssid->IEs + _FIXED_IE_LENGTH_, _COUNTRY_IE_, &len, bssid->IELength - _FIXED_IE_LENGTH_);
11417
if (!ie)
11418
return;
11419
if (len < 6)
11420
return;
11421
11422
ie += 2;
11423
p = ie;
11424
ie += len;
11425
11426
_rtw_memset(country, 0, 4);
11427
_rtw_memcpy(country, p, 3);
11428
p += 3;
11429
RTW_INFO("%s: 802.11d country=%s\n", __FUNCTION__, country);
11430
11431
i = 0;
11432
while ((ie - p) >= 3) {
11433
fcn = *(p++);
11434
noc = *(p++);
11435
p++;
11436
11437
for (j = 0; j < noc; j++) {
11438
if (fcn <= 14)
11439
channel = fcn + j; /* 2.4 GHz */
11440
else
11441
channel = fcn + j * 4; /* 5 GHz */
11442
11443
chplan_ap.Channel[i++] = channel;
11444
}
11445
}
11446
chplan_ap.Len = i;
11447
11448
#ifdef CONFIG_RTW_DEBUG
11449
i = 0;
11450
RTW_INFO("%s: AP[%s] channel plan {", __FUNCTION__, bssid->Ssid.Ssid);
11451
while ((i < chplan_ap.Len) && (chplan_ap.Channel[i] != 0)) {
11452
_RTW_INFO("%02d,", chplan_ap.Channel[i]);
11453
i++;
11454
}
11455
_RTW_INFO("}\n");
11456
#endif
11457
11458
chplan_sta = rtw_malloc(sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
11459
if (!chplan_sta)
11460
goto done_update_chplan_from_ap;
11461
11462
_rtw_memcpy(chplan_sta, rfctl->channel_set, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
11463
#ifdef CONFIG_RTW_DEBUG
11464
i = 0;
11465
RTW_INFO("%s: STA channel plan {", __FUNCTION__);
11466
while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
11467
_RTW_INFO("%02d(%c),", chplan_sta[i].ChannelNum, chplan_sta[i].ScanType == SCAN_PASSIVE ? 'p' : 'a');
11468
i++;
11469
}
11470
_RTW_INFO("}\n");
11471
#endif
11472
11473
_rtw_memset(rfctl->channel_set, 0, sizeof(rfctl->channel_set));
11474
chplan_new = rfctl->channel_set;
11475
11476
i = j = k = 0;
11477
if (pregistrypriv->wireless_mode & WIRELESS_11G) {
11478
do {
11479
if ((i == MAX_CHANNEL_NUM)
11480
|| (chplan_sta[i].ChannelNum == 0)
11481
|| (chplan_sta[i].ChannelNum > 14))
11482
break;
11483
11484
if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] > 14))
11485
break;
11486
11487
if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
11488
chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11489
chplan_new[k].ScanType = SCAN_ACTIVE;
11490
i++;
11491
j++;
11492
k++;
11493
} else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
11494
chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11495
#if 0
11496
chplan_new[k].ScanType = chplan_sta[i].ScanType;
11497
#else
11498
chplan_new[k].ScanType = SCAN_PASSIVE;
11499
#endif
11500
i++;
11501
k++;
11502
} else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
11503
chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11504
chplan_new[k].ScanType = SCAN_ACTIVE;
11505
j++;
11506
k++;
11507
}
11508
} while (1);
11509
11510
/* change AP not support channel to Passive scan */
11511
while ((i < MAX_CHANNEL_NUM)
11512
&& (chplan_sta[i].ChannelNum != 0)
11513
&& (chplan_sta[i].ChannelNum <= 14)) {
11514
chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11515
#if 0
11516
chplan_new[k].ScanType = chplan_sta[i].ScanType;
11517
#else
11518
chplan_new[k].ScanType = SCAN_PASSIVE;
11519
#endif
11520
i++;
11521
k++;
11522
}
11523
11524
/* add channel AP supported */
11525
while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14)) {
11526
chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11527
chplan_new[k].ScanType = SCAN_ACTIVE;
11528
j++;
11529
k++;
11530
}
11531
} else {
11532
/* keep original STA 2.4G channel plan */
11533
while ((i < MAX_CHANNEL_NUM)
11534
&& (chplan_sta[i].ChannelNum != 0)
11535
&& (chplan_sta[i].ChannelNum <= 14)) {
11536
chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11537
chplan_new[k].ScanType = chplan_sta[i].ScanType;
11538
i++;
11539
k++;
11540
}
11541
11542
/* skip AP 2.4G channel plan */
11543
while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] <= 14))
11544
j++;
11545
}
11546
11547
if (pregistrypriv->wireless_mode & WIRELESS_11A) {
11548
do {
11549
if ((i >= MAX_CHANNEL_NUM)
11550
|| (chplan_sta[i].ChannelNum == 0))
11551
break;
11552
11553
if ((j == chplan_ap.Len) || (chplan_ap.Channel[j] == 0))
11554
break;
11555
11556
if (chplan_sta[i].ChannelNum == chplan_ap.Channel[j]) {
11557
chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11558
chplan_new[k].ScanType = SCAN_ACTIVE;
11559
i++;
11560
j++;
11561
k++;
11562
} else if (chplan_sta[i].ChannelNum < chplan_ap.Channel[j]) {
11563
chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11564
#if 0
11565
chplan_new[k].ScanType = chplan_sta[i].ScanType;
11566
#else
11567
chplan_new[k].ScanType = SCAN_PASSIVE;
11568
#endif
11569
i++;
11570
k++;
11571
} else if (chplan_sta[i].ChannelNum > chplan_ap.Channel[j]) {
11572
chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11573
chplan_new[k].ScanType = SCAN_ACTIVE;
11574
j++;
11575
k++;
11576
}
11577
} while (1);
11578
11579
/* change AP not support channel to Passive scan */
11580
while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
11581
chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11582
#if 0
11583
chplan_new[k].ScanType = chplan_sta[i].ScanType;
11584
#else
11585
chplan_new[k].ScanType = SCAN_PASSIVE;
11586
#endif
11587
i++;
11588
k++;
11589
}
11590
11591
/* add channel AP supported */
11592
while ((j < chplan_ap.Len) && (chplan_ap.Channel[j] != 0)) {
11593
chplan_new[k].ChannelNum = chplan_ap.Channel[j];
11594
chplan_new[k].ScanType = SCAN_ACTIVE;
11595
j++;
11596
k++;
11597
}
11598
} else {
11599
/* keep original STA 5G channel plan */
11600
while ((i < MAX_CHANNEL_NUM) && (chplan_sta[i].ChannelNum != 0)) {
11601
chplan_new[k].ChannelNum = chplan_sta[i].ChannelNum;
11602
chplan_new[k].ScanType = chplan_sta[i].ScanType;
11603
i++;
11604
k++;
11605
}
11606
}
11607
11608
pmlmeext->update_channel_plan_by_ap_done = 1;
11609
11610
#ifdef CONFIG_RTW_DEBUG
11611
k = 0;
11612
RTW_INFO("%s: new STA channel plan {", __FUNCTION__);
11613
while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
11614
_RTW_INFO("%02d(%c),", chplan_new[k].ChannelNum, chplan_new[k].ScanType == SCAN_PASSIVE ? 'p' : 'c');
11615
k++;
11616
}
11617
_RTW_INFO("}\n");
11618
#endif
11619
11620
#if 0
11621
/* recover the right channel index */
11622
channel = chplan_sta[pmlmeext->sitesurvey_res.channel_idx].ChannelNum;
11623
k = 0;
11624
while ((k < MAX_CHANNEL_NUM) && (chplan_new[k].ChannelNum != 0)) {
11625
if (chplan_new[k].ChannelNum == channel) {
11626
RTW_INFO("%s: change mlme_ext sitesurvey channel index from %d to %d\n",
11627
__FUNCTION__, pmlmeext->sitesurvey_res.channel_idx, k);
11628
pmlmeext->sitesurvey_res.channel_idx = k;
11629
break;
11630
}
11631
k++;
11632
}
11633
#endif
11634
11635
done_update_chplan_from_ap:
11636
if (chplan_sta)
11637
rtw_mfree(chplan_sta, sizeof(RT_CHANNEL_INFO) * MAX_CHANNEL_NUM);
11638
}
11639
}
11640
#endif
11641
11642
/****************************************************************************
11643
11644
Following are the functions to report events
11645
11646
*****************************************************************************/
11647
11648
void report_survey_event(_adapter *padapter, union recv_frame *precv_frame)
11649
{
11650
struct cmd_obj *pcmd_obj;
11651
u8 *pevtcmd;
11652
u32 cmdsz;
11653
struct survey_event *psurvey_evt;
11654
struct C2HEvent_Header *pc2h_evt_hdr;
11655
struct mlme_ext_priv *pmlmeext;
11656
struct cmd_priv *pcmdpriv;
11657
/* u8 *pframe = precv_frame->u.hdr.rx_data; */
11658
/* uint len = precv_frame->u.hdr.len; */
11659
RT_CHANNEL_INFO *chset;
11660
int ch_set_idx = -1;
11661
11662
if (!padapter)
11663
return;
11664
11665
pmlmeext = &padapter->mlmeextpriv;
11666
pcmdpriv = &padapter->cmdpriv;
11667
chset = adapter_to_chset(padapter);
11668
11669
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11670
if (pcmd_obj == NULL)
11671
return;
11672
11673
cmdsz = (sizeof(struct survey_event) + sizeof(struct C2HEvent_Header));
11674
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11675
if (pevtcmd == NULL) {
11676
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11677
return;
11678
}
11679
11680
_rtw_init_listhead(&pcmd_obj->list);
11681
11682
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11683
pcmd_obj->cmdsz = cmdsz;
11684
pcmd_obj->parmbuf = pevtcmd;
11685
11686
pcmd_obj->rsp = NULL;
11687
pcmd_obj->rspsz = 0;
11688
11689
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11690
pc2h_evt_hdr->len = sizeof(struct survey_event);
11691
pc2h_evt_hdr->ID = GEN_EVT_CODE(_Survey);
11692
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11693
11694
psurvey_evt = (struct survey_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11695
11696
if (collect_bss_info(padapter, precv_frame, (WLAN_BSSID_EX *)&psurvey_evt->bss) == _FAIL) {
11697
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11698
rtw_mfree((u8 *)pevtcmd, cmdsz);
11699
return;
11700
}
11701
11702
#ifdef CONFIG_80211D
11703
process_80211d(padapter, &psurvey_evt->bss);
11704
#endif
11705
11706
ch_set_idx = rtw_chset_search_ch(chset, psurvey_evt->bss.Configuration.DSConfig);
11707
if (ch_set_idx >= 0) {
11708
if (psurvey_evt->bss.InfrastructureMode == Ndis802_11Infrastructure) {
11709
if (chset[ch_set_idx].ScanType == SCAN_PASSIVE
11710
&& !rtw_is_dfs_ch(psurvey_evt->bss.Configuration.DSConfig)
11711
) {
11712
RTW_INFO("%s: change ch:%d to active\n", __func__, psurvey_evt->bss.Configuration.DSConfig);
11713
chset[ch_set_idx].ScanType = SCAN_ACTIVE;
11714
}
11715
#ifdef CONFIG_DFS
11716
if (hidden_ssid_ap(&psurvey_evt->bss))
11717
chset[ch_set_idx].hidden_bss_cnt++;
11718
#endif
11719
}
11720
}
11721
11722
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11723
11724
pmlmeext->sitesurvey_res.bss_cnt++;
11725
11726
return;
11727
11728
}
11729
11730
void report_surveydone_event(_adapter *padapter)
11731
{
11732
struct cmd_obj *pcmd_obj;
11733
u8 *pevtcmd;
11734
u32 cmdsz;
11735
struct surveydone_event *psurveydone_evt;
11736
struct C2HEvent_Header *pc2h_evt_hdr;
11737
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11738
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11739
11740
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11741
if (pcmd_obj == NULL)
11742
return;
11743
11744
cmdsz = (sizeof(struct surveydone_event) + sizeof(struct C2HEvent_Header));
11745
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11746
if (pevtcmd == NULL) {
11747
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11748
return;
11749
}
11750
11751
_rtw_init_listhead(&pcmd_obj->list);
11752
11753
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11754
pcmd_obj->cmdsz = cmdsz;
11755
pcmd_obj->parmbuf = pevtcmd;
11756
11757
pcmd_obj->rsp = NULL;
11758
pcmd_obj->rspsz = 0;
11759
11760
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11761
pc2h_evt_hdr->len = sizeof(struct surveydone_event);
11762
pc2h_evt_hdr->ID = GEN_EVT_CODE(_SurveyDone);
11763
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11764
11765
psurveydone_evt = (struct surveydone_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11766
psurveydone_evt->bss_cnt = pmlmeext->sitesurvey_res.bss_cnt;
11767
11768
RTW_INFO("survey done event(%x) band:%d for "ADPT_FMT"\n", psurveydone_evt->bss_cnt, padapter->setband, ADPT_ARG(padapter));
11769
11770
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11771
11772
return;
11773
11774
}
11775
11776
u32 report_join_res(_adapter *padapter, int aid_res, u16 status)
11777
{
11778
struct cmd_obj *pcmd_obj;
11779
u8 *pevtcmd;
11780
u32 cmdsz;
11781
struct joinbss_event *pjoinbss_evt;
11782
struct C2HEvent_Header *pc2h_evt_hdr;
11783
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11784
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
11785
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11786
u32 ret = _FAIL;
11787
11788
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11789
if (pcmd_obj == NULL)
11790
goto exit;
11791
11792
cmdsz = (sizeof(struct joinbss_event) + sizeof(struct C2HEvent_Header));
11793
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11794
if (pevtcmd == NULL) {
11795
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11796
goto exit;
11797
}
11798
11799
_rtw_init_listhead(&pcmd_obj->list);
11800
11801
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11802
pcmd_obj->cmdsz = cmdsz;
11803
pcmd_obj->parmbuf = pevtcmd;
11804
11805
pcmd_obj->rsp = NULL;
11806
pcmd_obj->rspsz = 0;
11807
11808
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11809
pc2h_evt_hdr->len = sizeof(struct joinbss_event);
11810
pc2h_evt_hdr->ID = GEN_EVT_CODE(_JoinBss);
11811
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11812
11813
pjoinbss_evt = (struct joinbss_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11814
_rtw_memcpy((unsigned char *)(&(pjoinbss_evt->network.network)), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
11815
pjoinbss_evt->network.join_res = pjoinbss_evt->network.aid = aid_res;
11816
11817
RTW_INFO("report_join_res(%d, %u)\n", aid_res, status);
11818
11819
11820
rtw_joinbss_event_prehandle(padapter, (u8 *)&pjoinbss_evt->network, status);
11821
11822
11823
ret = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11824
11825
exit:
11826
return ret;
11827
}
11828
11829
void report_wmm_edca_update(_adapter *padapter)
11830
{
11831
struct cmd_obj *pcmd_obj;
11832
u8 *pevtcmd;
11833
u32 cmdsz;
11834
struct wmm_event *pwmm_event;
11835
struct C2HEvent_Header *pc2h_evt_hdr;
11836
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11837
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11838
11839
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11840
if (pcmd_obj == NULL)
11841
return;
11842
11843
cmdsz = (sizeof(struct wmm_event) + sizeof(struct C2HEvent_Header));
11844
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11845
if (pevtcmd == NULL) {
11846
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11847
return;
11848
}
11849
11850
_rtw_init_listhead(&pcmd_obj->list);
11851
11852
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11853
pcmd_obj->cmdsz = cmdsz;
11854
pcmd_obj->parmbuf = pevtcmd;
11855
11856
pcmd_obj->rsp = NULL;
11857
pcmd_obj->rspsz = 0;
11858
11859
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11860
pc2h_evt_hdr->len = sizeof(struct wmm_event);
11861
pc2h_evt_hdr->ID = GEN_EVT_CODE(_WMM);
11862
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11863
11864
pwmm_event = (struct wmm_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11865
pwmm_event->wmm = 0;
11866
11867
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11868
11869
return;
11870
11871
}
11872
11873
u32 report_del_sta_event(_adapter *padapter, unsigned char *MacAddr, unsigned short reason, bool enqueue, u8 locally_generated)
11874
{
11875
struct cmd_obj *pcmd_obj;
11876
u8 *pevtcmd;
11877
u32 cmdsz;
11878
struct sta_info *psta;
11879
int mac_id = -1;
11880
struct stadel_event *pdel_sta_evt;
11881
struct C2HEvent_Header *pc2h_evt_hdr;
11882
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11883
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11884
u8 res = _SUCCESS;
11885
11886
/* prepare cmd parameter */
11887
cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
11888
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11889
if (pevtcmd == NULL) {
11890
res = _FAIL;
11891
goto exit;
11892
}
11893
11894
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11895
pc2h_evt_hdr->len = sizeof(struct stadel_event);
11896
pc2h_evt_hdr->ID = GEN_EVT_CODE(_DelSTA);
11897
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11898
11899
pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11900
_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11901
_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
11902
psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
11903
if (psta)
11904
mac_id = (int)psta->cmn.mac_id;
11905
else
11906
mac_id = (-1);
11907
pdel_sta_evt->mac_id = mac_id;
11908
pdel_sta_evt->locally_generated = locally_generated;
11909
11910
if (!enqueue) {
11911
/* do directly */
11912
rtw_stadel_event_callback(padapter, (u8 *)pdel_sta_evt);
11913
rtw_mfree(pevtcmd, cmdsz);
11914
} else {
11915
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11916
if (pcmd_obj == NULL) {
11917
rtw_mfree(pevtcmd, cmdsz);
11918
res = _FAIL;
11919
goto exit;
11920
}
11921
11922
_rtw_init_listhead(&pcmd_obj->list);
11923
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11924
pcmd_obj->cmdsz = cmdsz;
11925
pcmd_obj->parmbuf = pevtcmd;
11926
11927
pcmd_obj->rsp = NULL;
11928
pcmd_obj->rspsz = 0;
11929
11930
res = rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11931
}
11932
11933
exit:
11934
11935
RTW_INFO(FUNC_ADPT_FMT" "MAC_FMT" mac_id=%d, enqueue:%d, res:%u\n"
11936
, FUNC_ADPT_ARG(padapter), MAC_ARG(MacAddr), mac_id, enqueue, res);
11937
11938
return res;
11939
}
11940
11941
void report_add_sta_event(_adapter *padapter, unsigned char *MacAddr)
11942
{
11943
struct cmd_obj *pcmd_obj;
11944
u8 *pevtcmd;
11945
u32 cmdsz;
11946
struct stassoc_event *padd_sta_evt;
11947
struct C2HEvent_Header *pc2h_evt_hdr;
11948
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
11949
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
11950
11951
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
11952
if (pcmd_obj == NULL)
11953
return;
11954
11955
cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
11956
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
11957
if (pevtcmd == NULL) {
11958
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
11959
return;
11960
}
11961
11962
_rtw_init_listhead(&pcmd_obj->list);
11963
11964
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
11965
pcmd_obj->cmdsz = cmdsz;
11966
pcmd_obj->parmbuf = pevtcmd;
11967
11968
pcmd_obj->rsp = NULL;
11969
pcmd_obj->rspsz = 0;
11970
11971
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
11972
pc2h_evt_hdr->len = sizeof(struct stassoc_event);
11973
pc2h_evt_hdr->ID = GEN_EVT_CODE(_AddSTA);
11974
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
11975
11976
padd_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
11977
_rtw_memcpy((unsigned char *)(&(padd_sta_evt->macaddr)), MacAddr, ETH_ALEN);
11978
11979
RTW_INFO("report_add_sta_event: add STA\n");
11980
11981
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
11982
11983
return;
11984
}
11985
11986
11987
bool rtw_port_switch_chk(_adapter *adapter)
11988
{
11989
bool switch_needed = _FALSE;
11990
#ifdef CONFIG_CONCURRENT_MODE
11991
#ifdef CONFIG_RUNTIME_PORT_SWITCH
11992
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
11993
struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(dvobj);
11994
_adapter *if_port0 = NULL;
11995
_adapter *if_port1 = NULL;
11996
struct mlme_ext_info *if_port0_mlmeinfo = NULL;
11997
struct mlme_ext_info *if_port1_mlmeinfo = NULL;
11998
int i;
11999
12000
for (i = 0; i < dvobj->iface_nums; i++) {
12001
if (get_hw_port(dvobj->padapters[i]) == HW_PORT0) {
12002
if_port0 = dvobj->padapters[i];
12003
if_port0_mlmeinfo = &(if_port0->mlmeextpriv.mlmext_info);
12004
} else if (get_hw_port(dvobj->padapters[i]) == HW_PORT1) {
12005
if_port1 = dvobj->padapters[i];
12006
if_port1_mlmeinfo = &(if_port1->mlmeextpriv.mlmext_info);
12007
}
12008
}
12009
12010
if (if_port0 == NULL) {
12011
rtw_warn_on(1);
12012
goto exit;
12013
}
12014
12015
if (if_port1 == NULL) {
12016
rtw_warn_on(1);
12017
goto exit;
12018
}
12019
12020
#ifdef DBG_RUNTIME_PORT_SWITCH
12021
RTW_INFO(FUNC_ADPT_FMT" wowlan_mode:%u\n"
12022
ADPT_FMT", port0, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n"
12023
ADPT_FMT", port1, mlmeinfo->state:0x%08x, p2p_state:%d, %d\n",
12024
FUNC_ADPT_ARG(adapter), pwrctl->wowlan_mode,
12025
ADPT_ARG(if_port0), if_port0_mlmeinfo->state, rtw_p2p_state(&if_port0->wdinfo), rtw_p2p_chk_state(&if_port0->wdinfo, P2P_STATE_NONE),
12026
ADPT_ARG(if_port1), if_port1_mlmeinfo->state, rtw_p2p_state(&if_port1->wdinfo), rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE));
12027
#endif /* DBG_RUNTIME_PORT_SWITCH */
12028
12029
#ifdef CONFIG_WOWLAN
12030
/* WOWLAN interface(primary, for now) should be port0 */
12031
if (pwrctl->wowlan_mode == _TRUE) {
12032
if (!is_primary_adapter(if_port0)) {
12033
RTW_INFO("%s "ADPT_FMT" enable WOWLAN\n", __func__, ADPT_ARG(if_port1));
12034
switch_needed = _TRUE;
12035
}
12036
goto exit;
12037
}
12038
#endif /* CONFIG_WOWLAN */
12039
12040
/* AP/Mesh should use port0 for ctl frame's ack */
12041
if ((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) {
12042
RTW_INFO("%s "ADPT_FMT" is AP/GO/Mesh\n", __func__, ADPT_ARG(if_port1));
12043
switch_needed = _TRUE;
12044
goto exit;
12045
}
12046
12047
/* GC should use port0 for p2p ps */
12048
if (((if_port1_mlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
12049
&& (if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12050
#ifdef CONFIG_P2P
12051
&& !rtw_p2p_chk_state(&if_port1->wdinfo, P2P_STATE_NONE)
12052
#endif
12053
&& !check_fwstate(&if_port1->mlmepriv, WIFI_UNDER_WPS)
12054
) {
12055
RTW_INFO("%s "ADPT_FMT" is GC\n", __func__, ADPT_ARG(if_port1));
12056
switch_needed = _TRUE;
12057
goto exit;
12058
}
12059
12060
/* port1 linked, but port0 not linked */
12061
if ((if_port1_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12062
&& !(if_port0_mlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
12063
&& ((if_port0_mlmeinfo->state & 0x03) != WIFI_FW_AP_STATE)
12064
) {
12065
RTW_INFO("%s "ADPT_FMT" is SINGLE_LINK\n", __func__, ADPT_ARG(if_port1));
12066
switch_needed = _TRUE;
12067
goto exit;
12068
}
12069
12070
exit:
12071
#ifdef DBG_RUNTIME_PORT_SWITCH
12072
RTW_INFO(FUNC_ADPT_FMT" ret:%d\n", FUNC_ADPT_ARG(adapter), switch_needed);
12073
#endif /* DBG_RUNTIME_PORT_SWITCH */
12074
#endif /* CONFIG_RUNTIME_PORT_SWITCH */
12075
#endif /* CONFIG_CONCURRENT_MODE */
12076
return switch_needed;
12077
}
12078
12079
/****************************************************************************
12080
12081
Following are the event callback functions
12082
12083
*****************************************************************************/
12084
12085
/* for sta/adhoc mode */
12086
void update_sta_info(_adapter *padapter, struct sta_info *psta)
12087
{
12088
_irqL irqL;
12089
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
12090
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12091
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12092
12093
/* ERP */
12094
VCS_update(padapter, psta);
12095
12096
#ifdef CONFIG_80211N_HT
12097
/* HT */
12098
if (pmlmepriv->htpriv.ht_option) {
12099
psta->htpriv.ht_option = _TRUE;
12100
12101
psta->htpriv.ampdu_enable = pmlmepriv->htpriv.ampdu_enable;
12102
12103
psta->htpriv.rx_ampdu_min_spacing = (pmlmeinfo->HT_caps.u.HT_cap_element.AMPDU_para & IEEE80211_HT_CAP_AMPDU_DENSITY) >> 2;
12104
12105
if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_20))
12106
psta->htpriv.sgi_20m = _TRUE;
12107
12108
if (support_short_GI(padapter, &(pmlmeinfo->HT_caps), CHANNEL_WIDTH_40))
12109
psta->htpriv.sgi_40m = _TRUE;
12110
12111
psta->qos_option = _TRUE;
12112
12113
psta->htpriv.ldpc_cap = pmlmepriv->htpriv.ldpc_cap;
12114
psta->htpriv.stbc_cap = pmlmepriv->htpriv.stbc_cap;
12115
psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
12116
12117
_rtw_memcpy(&psta->htpriv.ht_cap, &pmlmeinfo->HT_caps, sizeof(struct rtw_ieee80211_ht_cap));
12118
#ifdef CONFIG_BEAMFORMING
12119
psta->htpriv.beamform_cap = pmlmepriv->htpriv.beamform_cap;
12120
psta->cmn.bf_info.ht_beamform_cap = pmlmepriv->htpriv.beamform_cap;
12121
#endif
12122
} else
12123
#endif /* CONFIG_80211N_HT */
12124
{
12125
#ifdef CONFIG_80211N_HT
12126
psta->htpriv.ht_option = _FALSE;
12127
psta->htpriv.ampdu_enable = _FALSE;
12128
psta->htpriv.tx_amsdu_enable = _FALSE;
12129
psta->htpriv.sgi_20m = _FALSE;
12130
psta->htpriv.sgi_40m = _FALSE;
12131
#endif /* CONFIG_80211N_HT */
12132
psta->qos_option = _FALSE;
12133
12134
}
12135
12136
#ifdef CONFIG_80211N_HT
12137
psta->htpriv.ch_offset = pmlmeext->cur_ch_offset;
12138
12139
psta->htpriv.agg_enable_bitmap = 0x0;/* reset */
12140
psta->htpriv.candidate_tid_bitmap = 0x0;/* reset */
12141
#endif /* CONFIG_80211N_HT */
12142
12143
psta->cmn.bw_mode = pmlmeext->cur_bwmode;
12144
12145
/* QoS */
12146
if (pmlmepriv->qospriv.qos_option)
12147
psta->qos_option = _TRUE;
12148
12149
#ifdef CONFIG_80211AC_VHT
12150
_rtw_memcpy(&psta->vhtpriv, &pmlmepriv->vhtpriv, sizeof(struct vht_priv));
12151
if (psta->vhtpriv.vht_option) {
12152
psta->cmn.ra_info.is_vht_enable = _TRUE;
12153
#ifdef CONFIG_BEAMFORMING
12154
psta->vhtpriv.beamform_cap = pmlmepriv->vhtpriv.beamform_cap;
12155
psta->cmn.bf_info.vht_beamform_cap = pmlmepriv->vhtpriv.beamform_cap;
12156
#endif /*CONFIG_BEAMFORMING*/
12157
}
12158
#endif /* CONFIG_80211AC_VHT */
12159
psta->cmn.ra_info.is_support_sgi = query_ra_short_GI(psta, rtw_get_tx_bw_mode(padapter, psta));
12160
update_ldpc_stbc_cap(psta);
12161
12162
_enter_critical_bh(&psta->lock, &irqL);
12163
psta->state = _FW_LINKED;
12164
_exit_critical_bh(&psta->lock, &irqL);
12165
12166
}
12167
12168
static void rtw_mlmeext_disconnect(_adapter *padapter)
12169
{
12170
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12171
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12172
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12173
u8 self_action = MLME_ACTION_UNKNOWN;
12174
u8 state_backup = (pmlmeinfo->state & 0x03);
12175
u8 ASIX_ID[] = {0x00, 0x0E, 0xC6};
12176
12177
if (MLME_IS_AP(padapter))
12178
self_action = MLME_AP_STOPPED;
12179
else if (MLME_IS_MESH(padapter))
12180
self_action = MLME_MESH_STOPPED;
12181
else if (MLME_IS_STA(padapter))
12182
self_action = MLME_STA_DISCONNECTED;
12183
else if (MLME_IS_ADHOC(padapter) || MLME_IS_ADHOC_MASTER(padapter))
12184
self_action = MLME_ADHOC_STOPPED;
12185
else {
12186
RTW_INFO("state:0x%x\n", MLME_STATE(padapter));
12187
rtw_warn_on(1);
12188
}
12189
12190
/* set_opmode_cmd(padapter, infra_client_with_mlme); */
12191
#ifdef CONFIG_HW_P0_TSF_SYNC
12192
if (self_action == MLME_STA_DISCONNECTED)
12193
correct_TSF(padapter, self_action);
12194
#endif
12195
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
12196
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12197
if (self_action == MLME_STA_DISCONNECTED)
12198
rtw_hal_rcr_set_chk_bssid(padapter, self_action);
12199
12200
/* set MSR to no link state->infra. mode */
12201
Set_MSR(padapter, _HW_STATE_STATION_);
12202
12203
/* check if sta is ASIX peer and fix IOT issue if it is. */
12204
if (_rtw_memcmp(get_my_bssid(&pmlmeinfo->network) , ASIX_ID , 3)) {
12205
u8 iot_flag = _FALSE;
12206
rtw_hal_set_hwreg(padapter, HW_VAR_ASIX_IOT, (u8 *)(&iot_flag));
12207
}
12208
pmlmeinfo->state = WIFI_FW_NULL_STATE;
12209
12210
#ifdef CONFIG_MCC_MODE
12211
/* mcc disconnect setting before download LPS rsvd page */
12212
rtw_hal_set_mcc_setting_disconnect(padapter);
12213
#endif /* CONFIG_MCC_MODE */
12214
12215
if (state_backup == WIFI_FW_STATION_STATE) {
12216
if (rtw_port_switch_chk(padapter) == _TRUE) {
12217
rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12218
#ifdef CONFIG_LPS
12219
{
12220
_adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
12221
if (port0_iface)
12222
rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
12223
}
12224
#endif
12225
}
12226
}
12227
12228
/* switch to the 20M Hz mode after disconnect */
12229
pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
12230
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
12231
#ifdef CONFIG_CTRL_TXSS_BY_TP
12232
pmlmeext->txss_1ss = _FALSE;
12233
#endif
12234
12235
#ifdef CONFIG_FCS_MODE
12236
if (EN_FCS(padapter))
12237
rtw_hal_set_hwreg(padapter, HW_VAR_STOP_FCS_MODE, NULL);
12238
#endif
12239
12240
if (!(MLME_IS_STA(padapter) && MLME_IS_OPCH_SW(padapter))) {
12241
/* DFS and channel status no need to check here for STA under OPCH_SW */
12242
u8 ch, bw, offset;
12243
12244
#ifdef CONFIG_DFS_MASTER
12245
rtw_dfs_rd_en_decision(padapter, self_action, 0);
12246
#endif
12247
12248
if (rtw_mi_get_ch_setting_union_no_self(padapter, &ch, &bw, &offset) != 0) {
12249
set_channel_bwmode(padapter, ch, offset, bw);
12250
rtw_mi_update_union_chan_inf(padapter, ch, offset, bw);
12251
}
12252
}
12253
12254
flush_all_cam_entry(padapter);
12255
12256
_cancel_timer_ex(&pmlmeext->link_timer);
12257
12258
/* pmlmepriv->LinkDetectInfo.TrafficBusyState = _FALSE; */
12259
pmlmepriv->LinkDetectInfo.TrafficTransitionCount = 0;
12260
pmlmepriv->LinkDetectInfo.LowPowerTransitionCount = 0;
12261
12262
#ifdef CONFIG_TDLS
12263
padapter->tdlsinfo.ap_prohibited = _FALSE;
12264
12265
/* For TDLS channel switch, currently we only allow it to work in wifi logo test mode */
12266
if (padapter->registrypriv.wifi_spec == 1)
12267
padapter->tdlsinfo.ch_switch_prohibited = _FALSE;
12268
#endif /* CONFIG_TDLS */
12269
12270
#ifdef CONFIG_WMMPS_STA
12271
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
12272
/* reset currently related uapsd setting when the connection has broken */
12273
pmlmepriv->qospriv.uapsd_max_sp_len = 0;
12274
pmlmepriv->qospriv.uapsd_tid = 0;
12275
pmlmepriv->qospriv.uapsd_tid_delivery_enabled = 0;
12276
pmlmepriv->qospriv.uapsd_tid_trigger_enabled = 0;
12277
pmlmepriv->qospriv.uapsd_ap_supported = 0;
12278
}
12279
#endif /* CONFIG_WMMPS_STA */
12280
#ifdef CONFIG_RTS_FULL_BW
12281
rtw_set_rts_bw(padapter);
12282
#endif/*CONFIG_RTS_FULL_BW*/
12283
12284
}
12285
12286
void mlmeext_joinbss_event_callback(_adapter *padapter, int join_res)
12287
{
12288
struct sta_info *psta;
12289
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12290
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12291
WLAN_BSSID_EX *cur_network = &(pmlmeinfo->network);
12292
struct sta_priv *pstapriv = &padapter->stapriv;
12293
u8 join_type;
12294
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12295
12296
#ifndef CONFIG_IOCTL_CFG80211
12297
struct security_priv *psecuritypriv = &padapter->securitypriv;
12298
#endif
12299
12300
if (pmlmepriv->wpa_phase == _TRUE)
12301
pmlmepriv->wpa_phase = _FALSE;
12302
12303
if (join_res < 0) {
12304
join_type = 1;
12305
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12306
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, null_addr);
12307
if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE)
12308
rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_DISCONNECTED);
12309
12310
goto exit_mlmeext_joinbss_event_callback;
12311
}
12312
12313
#ifdef CONFIG_ARP_KEEP_ALIVE
12314
pmlmepriv->bGetGateway = 1;
12315
pmlmepriv->GetGatewayTryCnt = 0;
12316
#endif
12317
12318
if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12319
/* update bc/mc sta_info */
12320
update_bmc_sta(padapter);
12321
}
12322
12323
12324
/* turn on dynamic functions */
12325
/* Switch_DM_Func(padapter, DYNAMIC_ALL_FUNC_ENABLE, _TRUE); */
12326
12327
/* update IOT-releated issue */
12328
update_IOT_info(padapter);
12329
12330
#ifdef CONFIG_RTS_FULL_BW
12331
rtw_set_rts_bw(padapter);
12332
#endif/*CONFIG_RTS_FULL_BW*/
12333
12334
rtw_hal_set_hwreg(padapter, HW_VAR_BASIC_RATE, cur_network->SupportedRates);
12335
12336
/* BCN interval */
12337
rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)(&pmlmeinfo->bcn_interval));
12338
12339
/* udpate capability */
12340
update_capinfo(padapter, pmlmeinfo->capability);
12341
12342
/* WMM, Update EDCA param */
12343
WMMOnAssocRsp(padapter);
12344
#ifdef CONFIG_80211N_HT
12345
/* HT */
12346
HTOnAssocRsp(padapter);
12347
#endif /* CONFIG_80211N_HT */
12348
#ifdef CONFIG_80211AC_VHT
12349
/* VHT */
12350
VHTOnAssocRsp(padapter);
12351
#endif
12352
12353
psta = rtw_get_stainfo(pstapriv, cur_network->MacAddress);
12354
if (psta) { /* only for infra. mode */
12355
psta->wireless_mode = pmlmeext->cur_wireless_mode;
12356
12357
/* set per sta rate after updating HT cap. */
12358
set_sta_rate(padapter, psta);
12359
12360
rtw_sta_media_status_rpt(padapter, psta, 1);
12361
12362
/* wakeup macid after join bss successfully to ensure
12363
the subsequent data frames can be sent out normally */
12364
rtw_hal_macid_wakeup(padapter, psta->cmn.mac_id);
12365
12366
rtw_xmit_queue_clear(psta);
12367
}
12368
12369
#ifndef CONFIG_IOCTL_CFG80211
12370
if (is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
12371
rtw_sec_restore_wep_key(padapter);
12372
#endif /* CONFIG_IOCTL_CFG80211 */
12373
12374
if (rtw_port_switch_chk(padapter) == _TRUE)
12375
rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
12376
12377
join_type = 2;
12378
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12379
12380
if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE) {
12381
rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTED);
12382
12383
/* correcting TSF */
12384
correct_TSF(padapter, MLME_STA_CONNECTED);
12385
12386
/* set_link_timer(pmlmeext, DISCONNECT_TO); */
12387
}
12388
12389
#ifdef CONFIG_LPS
12390
#ifndef CONFIG_FW_MULTI_PORT_SUPPORT
12391
if (get_hw_port(padapter) == HW_PORT0)
12392
#endif
12393
rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
12394
#endif
12395
12396
#ifdef CONFIG_BEAMFORMING
12397
if (psta)
12398
beamforming_wk_cmd(padapter, BEAMFORMING_CTRL_ENTER, (u8 *)psta, sizeof(struct sta_info), 0);
12399
#endif/*CONFIG_BEAMFORMING*/
12400
12401
exit_mlmeext_joinbss_event_callback:
12402
12403
rtw_join_done_chk_ch(padapter, join_res);
12404
#ifdef CONFIG_RTW_REPEATER_SON
12405
rtw_rson_join_done(padapter);
12406
#endif
12407
12408
#ifdef CONFIG_PCI_DYNAMIC_ASPM
12409
rtw_pci_dynamic_aspm_set_mode(padapter, ASPM_MODE_PERF);
12410
#endif
12411
12412
RTW_INFO("=>%s - End to Connection without 4-way\n", __FUNCTION__);
12413
}
12414
12415
/* currently only adhoc mode will go here */
12416
void mlmeext_sta_add_event_callback(_adapter *padapter, struct sta_info *psta)
12417
{
12418
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
12419
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12420
u8 join_type;
12421
12422
RTW_INFO("%s\n", __FUNCTION__);
12423
12424
if ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) {
12425
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) { /* adhoc master or sta_count>1 */
12426
/* nothing to do */
12427
} else { /* adhoc client */
12428
/* update TSF Value */
12429
/* update_TSF(pmlmeext, pframe, len); */
12430
12431
/* correcting TSF */
12432
correct_TSF(padapter, MLME_ADHOC_STARTED);
12433
12434
/* start beacon */
12435
if (send_beacon(padapter) == _FAIL)
12436
rtw_warn_on(1);
12437
12438
pmlmeinfo->state |= WIFI_FW_ASSOC_SUCCESS;
12439
}
12440
12441
join_type = 2;
12442
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
12443
}
12444
12445
/* update adhoc sta_info */
12446
update_sta_info(padapter, psta);
12447
12448
rtw_hal_update_sta_ra_info(padapter, psta);
12449
12450
/* ToDo: HT for Ad-hoc */
12451
psta->wireless_mode = rtw_check_network_type(psta->bssrateset, psta->bssratelen, pmlmeext->cur_channel);
12452
rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, psta, _TRUE);
12453
12454
/* rate radaptive */
12455
Update_RA_Entry(padapter, psta);
12456
}
12457
12458
void mlmeext_sta_del_event_callback(_adapter *padapter)
12459
{
12460
if (is_client_associated_to_ap(padapter) || is_IBSS_empty(padapter))
12461
rtw_mlmeext_disconnect(padapter);
12462
}
12463
12464
/****************************************************************************
12465
12466
Following are the functions for the timer handlers
12467
12468
*****************************************************************************/
12469
void _linked_info_dump(_adapter *padapter)
12470
{
12471
if (padapter->bLinkInfoDump) {
12472
rtw_hal_get_def_var(padapter, HW_DEF_RA_INFO_DUMP, RTW_DBGDUMP);
12473
rtw_hal_set_odm_var(padapter, HAL_ODM_RX_INFO_DUMP, RTW_DBGDUMP, _FALSE);
12474
}
12475
}
12476
/********************************************************************
12477
12478
When station does not receive any packet in MAX_CONTINUAL_NORXPACKET_COUNT*2 seconds,
12479
recipient station will teardown the block ack by issuing DELBA frame.
12480
12481
*********************************************************************/
12482
void rtw_delba_check(_adapter *padapter, struct sta_info *psta, u8 from_timer)
12483
{
12484
int i = 0;
12485
int ret = _SUCCESS;
12486
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12487
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12488
12489
/*
12490
IOT issue,occur Broadcom ap(Buffalo WZR-D1800H,Netgear R6300).
12491
AP is originator.AP does not transmit unicast packets when STA response its BAR.
12492
This case probably occur ap issue BAR after AP builds BA.
12493
12494
Follow 802.11 spec, STA shall maintain an inactivity timer for every negotiated Block Ack setup.
12495
The inactivity timer is not reset when MPDUs corresponding to other TIDs are received.
12496
*/
12497
if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_BROADCOM) {
12498
for (i = 0; i < TID_NUM ; i++) {
12499
if ((psta->recvreorder_ctrl[i].enable) &&
12500
(sta_rx_data_qos_pkts(psta, i) == sta_last_rx_data_qos_pkts(psta, i)) ) {
12501
if (_TRUE == rtw_inc_and_chk_continual_no_rx_packet(psta, i)) {
12502
/* send a DELBA frame to the peer STA with the Reason Code field set to TIMEOUT */
12503
if (!from_timer)
12504
ret = issue_del_ba_ex(padapter, psta->cmn.mac_addr, i, 39, 0, 3, 1);
12505
else
12506
issue_del_ba(padapter, psta->cmn.mac_addr, i, 39, 0);
12507
psta->recvreorder_ctrl[i].enable = _FALSE;
12508
if (ret != _FAIL)
12509
psta->recvreorder_ctrl[i].ampdu_size = RX_AMPDU_SIZE_INVALID;
12510
rtw_reset_continual_no_rx_packet(psta, i);
12511
}
12512
} else {
12513
/* The inactivity timer is reset when MPDUs to the TID is received. */
12514
rtw_reset_continual_no_rx_packet(psta, i);
12515
}
12516
}
12517
}
12518
}
12519
12520
u8 chk_ap_is_alive(_adapter *padapter, struct sta_info *psta)
12521
{
12522
u8 ret = _FALSE;
12523
#ifdef DBG_EXPIRATION_CHK
12524
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12525
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12526
12527
RTW_INFO(FUNC_ADPT_FMT" rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12528
/*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12529
", retry:%u\n"
12530
, FUNC_ADPT_ARG(padapter)
12531
, STA_RX_PKTS_DIFF_ARG(psta)
12532
, psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12533
, psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12534
/*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12535
, psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12536
, psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12537
, pmlmeinfo->bcn_interval*/
12538
, pmlmeext->retry
12539
);
12540
12541
RTW_INFO(FUNC_ADPT_FMT" tx_pkts:%llu, link_count:%u\n", FUNC_ADPT_ARG(padapter)
12542
, sta_tx_pkts(psta)
12543
, pmlmeinfo->link_count
12544
);
12545
#endif
12546
12547
if ((sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta))
12548
&& sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12549
&& sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta)
12550
)
12551
ret = _FALSE;
12552
else
12553
ret = _TRUE;
12554
12555
sta_update_last_rx_pkts(psta);
12556
12557
return ret;
12558
}
12559
12560
u8 chk_adhoc_peer_is_alive(struct sta_info *psta)
12561
{
12562
u8 ret = _TRUE;
12563
12564
#ifdef DBG_EXPIRATION_CHK
12565
RTW_INFO("sta:"MAC_FMT", rssi:%d, rx:"STA_PKTS_FMT", beacon:%llu, probersp_to_self:%llu"
12566
/*", probersp_bm:%llu, probersp_uo:%llu, probereq:%llu, BI:%u"*/
12567
", expire_to:%u\n"
12568
, MAC_ARG(psta->cmn.mac_addr)
12569
, psta->cmn.rssi_stat.rssi
12570
, STA_RX_PKTS_DIFF_ARG(psta)
12571
, psta->sta_stats.rx_beacon_pkts - psta->sta_stats.last_rx_beacon_pkts
12572
, psta->sta_stats.rx_probersp_pkts - psta->sta_stats.last_rx_probersp_pkts
12573
/*, psta->sta_stats.rx_probersp_bm_pkts - psta->sta_stats.last_rx_probersp_bm_pkts
12574
, psta->sta_stats.rx_probersp_uo_pkts - psta->sta_stats.last_rx_probersp_uo_pkts
12575
, psta->sta_stats.rx_probereq_pkts - psta->sta_stats.last_rx_probereq_pkts
12576
, pmlmeinfo->bcn_interval*/
12577
, psta->expire_to
12578
);
12579
#endif
12580
12581
if (sta_rx_data_pkts(psta) == sta_last_rx_data_pkts(psta)
12582
&& sta_rx_beacon_pkts(psta) == sta_last_rx_beacon_pkts(psta)
12583
&& sta_rx_probersp_pkts(psta) == sta_last_rx_probersp_pkts(psta))
12584
ret = _FALSE;
12585
12586
sta_update_last_rx_pkts(psta);
12587
12588
return ret;
12589
}
12590
12591
#ifdef CONFIG_TDLS
12592
u8 chk_tdls_peer_sta_is_alive(_adapter *padapter, struct sta_info *psta)
12593
{
12594
if ((psta->sta_stats.rx_data_pkts == psta->sta_stats.last_rx_data_pkts)
12595
&& (psta->sta_stats.rx_tdls_disc_rsp_pkts == psta->sta_stats.last_rx_tdls_disc_rsp_pkts))
12596
return _FALSE;
12597
12598
return _TRUE;
12599
}
12600
12601
void linked_status_chk_tdls(_adapter *padapter)
12602
{
12603
struct candidate_pool {
12604
struct sta_info *psta;
12605
u8 addr[ETH_ALEN];
12606
};
12607
struct sta_priv *pstapriv = &padapter->stapriv;
12608
_irqL irqL;
12609
u8 ack_chk;
12610
struct sta_info *psta;
12611
int i, num_teardown = 0, num_checkalive = 0;
12612
_list *plist, *phead;
12613
struct tdls_txmgmt txmgmt;
12614
struct candidate_pool checkalive[MAX_ALLOWED_TDLS_STA_NUM];
12615
struct candidate_pool teardown[MAX_ALLOWED_TDLS_STA_NUM];
12616
u8 tdls_sta_max = _FALSE;
12617
12618
#define ALIVE_MIN 2
12619
#define ALIVE_MAX 5
12620
12621
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
12622
_rtw_memset(checkalive, 0x00, sizeof(checkalive));
12623
_rtw_memset(teardown, 0x00, sizeof(teardown));
12624
12625
if ((padapter->tdlsinfo.link_established == _TRUE)) {
12626
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12627
for (i = 0; i < NUM_STA; i++) {
12628
phead = &(pstapriv->sta_hash[i]);
12629
plist = get_next(phead);
12630
12631
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12632
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12633
plist = get_next(plist);
12634
12635
if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
12636
psta->alive_count++;
12637
if (psta->alive_count >= ALIVE_MIN) {
12638
if (chk_tdls_peer_sta_is_alive(padapter, psta) == _FALSE) {
12639
if (psta->alive_count < ALIVE_MAX) {
12640
_rtw_memcpy(checkalive[num_checkalive].addr, psta->cmn.mac_addr, ETH_ALEN);
12641
checkalive[num_checkalive].psta = psta;
12642
num_checkalive++;
12643
} else {
12644
_rtw_memcpy(teardown[num_teardown].addr, psta->cmn.mac_addr, ETH_ALEN);
12645
teardown[num_teardown].psta = psta;
12646
num_teardown++;
12647
}
12648
} else
12649
psta->alive_count = 0;
12650
}
12651
psta->sta_stats.last_rx_data_pkts = psta->sta_stats.rx_data_pkts;
12652
psta->sta_stats.last_rx_tdls_disc_rsp_pkts = psta->sta_stats.rx_tdls_disc_rsp_pkts;
12653
12654
if ((num_checkalive >= MAX_ALLOWED_TDLS_STA_NUM) || (num_teardown >= MAX_ALLOWED_TDLS_STA_NUM)) {
12655
tdls_sta_max = _TRUE;
12656
break;
12657
}
12658
}
12659
}
12660
12661
if (tdls_sta_max == _TRUE)
12662
break;
12663
}
12664
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12665
12666
if (num_checkalive > 0) {
12667
for (i = 0; i < num_checkalive; i++) {
12668
_rtw_memcpy(txmgmt.peer, checkalive[i].addr, ETH_ALEN);
12669
issue_tdls_dis_req(padapter, &txmgmt);
12670
issue_tdls_dis_req(padapter, &txmgmt);
12671
issue_tdls_dis_req(padapter, &txmgmt);
12672
}
12673
}
12674
12675
if (num_teardown > 0) {
12676
for (i = 0; i < num_teardown; i++) {
12677
RTW_INFO("[%s %d] Send teardown to "MAC_FMT"\n", __FUNCTION__, __LINE__, MAC_ARG(teardown[i].addr));
12678
txmgmt.status_code = _RSON_TDLS_TEAR_TOOFAR_;
12679
_rtw_memcpy(txmgmt.peer, teardown[i].addr, ETH_ALEN);
12680
issue_tdls_teardown(padapter, &txmgmt, _FALSE);
12681
}
12682
}
12683
}
12684
12685
}
12686
#endif /* CONFIG_TDLS */
12687
12688
inline int rtw_get_rx_chk_limit(_adapter *adapter)
12689
{
12690
return adapter->stapriv.rx_chk_limit;
12691
}
12692
12693
inline void rtw_set_rx_chk_limit(_adapter *adapter, int limit)
12694
{
12695
adapter->stapriv.rx_chk_limit = limit;
12696
}
12697
12698
/* from_timer == 1 means driver is in LPS */
12699
void linked_status_chk(_adapter *padapter, u8 from_timer)
12700
{
12701
u32 i;
12702
struct sta_info *psta;
12703
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12704
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
12705
struct sta_priv *pstapriv = &padapter->stapriv;
12706
#if defined(CONFIG_ARP_KEEP_ALIVE) || defined(CONFIG_LAYER2_ROAMING)
12707
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
12708
#endif
12709
#ifdef CONFIG_LAYER2_ROAMING
12710
struct recv_priv *precvpriv = &padapter->recvpriv;
12711
#endif
12712
12713
if (padapter->registrypriv.mp_mode == _TRUE)
12714
return;
12715
12716
if (is_client_associated_to_ap(padapter)) {
12717
/* linked infrastructure client mode */
12718
12719
int tx_chk = _SUCCESS, rx_chk = _SUCCESS;
12720
int rx_chk_limit;
12721
int link_count_limit;
12722
12723
#if defined(CONFIG_RTW_REPEATER_SON)
12724
rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_PROCESS);
12725
#elif defined(CONFIG_LAYER2_ROAMING)
12726
if (rtw_chk_roam_flags(padapter, RTW_ROAM_ACTIVE)) {
12727
RTW_INFO("signal_strength_data.avg_val = %d\n", precvpriv->signal_strength_data.avg_val);
12728
if ((precvpriv->signal_strength_data.avg_val < pmlmepriv->roam_rssi_threshold)
12729
&& (rtw_get_passing_time_ms(pmlmepriv->last_roaming) >= pmlmepriv->roam_scan_int*2000)) {
12730
#ifdef CONFIG_RTW_80211K
12731
rtw_roam_nb_discover(padapter, _FALSE);
12732
#endif
12733
pmlmepriv->need_to_roam = _TRUE;
12734
rtw_drv_scan_by_self(padapter, RTW_AUTO_SCAN_REASON_ROAM);
12735
pmlmepriv->last_roaming = rtw_get_current_time();
12736
} else
12737
pmlmepriv->need_to_roam = _FALSE;
12738
}
12739
#endif
12740
#ifdef CONFIG_MCC_MODE
12741
/*
12742
* due to tx ps null date to ao, so ap doest not tx pkt to driver
12743
* we may check chk_ap_is_alive fail, and may issue_probereq to wrong channel under sitesurvey
12744
* don't keep alive check under MCC
12745
*/
12746
if (rtw_hal_mcc_link_status_chk(padapter, __func__) == _FALSE)
12747
return;
12748
#endif
12749
12750
rx_chk_limit = rtw_get_rx_chk_limit(padapter);
12751
12752
#ifdef CONFIG_ARP_KEEP_ALIVE
12753
if (!from_timer && pmlmepriv->bGetGateway == 1 && pmlmepriv->GetGatewayTryCnt < 3) {
12754
RTW_INFO("do rtw_gw_addr_query() : %d\n", pmlmepriv->GetGatewayTryCnt);
12755
pmlmepriv->GetGatewayTryCnt++;
12756
if (rtw_gw_addr_query(padapter) == 0)
12757
pmlmepriv->bGetGateway = 0;
12758
else {
12759
_rtw_memset(pmlmepriv->gw_ip, 0, 4);
12760
_rtw_memset(pmlmepriv->gw_mac_addr, 0, ETH_ALEN);
12761
}
12762
}
12763
#endif
12764
#ifdef CONFIG_P2P
12765
if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
12766
if (!from_timer)
12767
link_count_limit = 3; /* 8 sec */
12768
else
12769
link_count_limit = 15; /* 32 sec */
12770
} else
12771
#endif /* CONFIG_P2P */
12772
{
12773
if (!from_timer)
12774
link_count_limit = 7; /* 16 sec */
12775
else
12776
link_count_limit = 29; /* 60 sec */
12777
}
12778
12779
#ifdef CONFIG_TDLS
12780
#ifdef CONFIG_TDLS_CH_SW
12781
if (ATOMIC_READ(&padapter->tdlsinfo.chsw_info.chsw_on) == _TRUE)
12782
return;
12783
#endif /* CONFIG_TDLS_CH_SW */
12784
12785
#ifdef CONFIG_TDLS_AUTOCHECKALIVE
12786
linked_status_chk_tdls(padapter);
12787
#endif /* CONFIG_TDLS_AUTOCHECKALIVE */
12788
#endif /* CONFIG_TDLS */
12789
12790
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
12791
if (psta != NULL) {
12792
bool is_p2p_enable = _FALSE;
12793
#ifdef CONFIG_P2P
12794
is_p2p_enable = !rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE);
12795
#endif
12796
12797
#ifdef CONFIG_ISSUE_DELBA_WHEN_NO_TRAFFIC
12798
/*issue delba when ap does not tx data packet that is Broadcom ap */
12799
rtw_delba_check(padapter, psta, from_timer);
12800
#endif
12801
if (chk_ap_is_alive(padapter, psta) == _FALSE)
12802
rx_chk = _FAIL;
12803
12804
if (sta_last_tx_pkts(psta) == sta_tx_pkts(psta))
12805
tx_chk = _FAIL;
12806
12807
#ifdef CONFIG_ACTIVE_KEEP_ALIVE_CHECK
12808
if (!from_timer && pmlmeext->active_keep_alive_check && (rx_chk == _FAIL || tx_chk == _FAIL)
12809
) {
12810
u8 backup_ch = 0, backup_bw = 0, backup_offset = 0;
12811
u8 union_ch = 0, union_bw = 0, union_offset = 0;
12812
u8 switch_channel_by_drv = _TRUE;
12813
12814
12815
#ifdef CONFIG_MCC_MODE
12816
if (MCC_EN(padapter)) {
12817
/* driver doesn't switch channel under MCC */
12818
if (rtw_hal_check_mcc_status(padapter, MCC_STATUS_DOING_MCC))
12819
switch_channel_by_drv = _FALSE;
12820
}
12821
#endif
12822
if (switch_channel_by_drv) {
12823
if (!rtw_mi_get_ch_setting_union(padapter, &union_ch, &union_bw, &union_offset)
12824
|| pmlmeext->cur_channel != union_ch)
12825
goto bypass_active_keep_alive;
12826
12827
/* switch to correct channel of current network before issue keep-alive frames */
12828
if (rtw_get_oper_ch(padapter) != pmlmeext->cur_channel) {
12829
backup_ch = rtw_get_oper_ch(padapter);
12830
backup_bw = rtw_get_oper_bw(padapter);
12831
backup_offset = rtw_get_oper_choffset(padapter);
12832
set_channel_bwmode(padapter, union_ch, union_offset, union_bw);
12833
}
12834
}
12835
12836
if (rx_chk != _SUCCESS)
12837
issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, psta->cmn.mac_addr, 0, 0, 3, 1);
12838
12839
if ((tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit) || rx_chk != _SUCCESS) {
12840
if (rtw_mi_check_fwstate(padapter, _FW_UNDER_SURVEY))
12841
tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 1, 3, 1);
12842
else
12843
tx_chk = issue_nulldata(padapter, psta->cmn.mac_addr, 0, 3, 1);
12844
/* if tx acked and p2p disabled, set rx_chk _SUCCESS to reset retry count */
12845
if (tx_chk == _SUCCESS && !is_p2p_enable)
12846
rx_chk = _SUCCESS;
12847
}
12848
12849
/* back to the original operation channel */
12850
if (backup_ch > 0 && switch_channel_by_drv)
12851
set_channel_bwmode(padapter, backup_ch, backup_offset, backup_bw);
12852
12853
bypass_active_keep_alive:
12854
;
12855
} else
12856
#endif /* CONFIG_ACTIVE_KEEP_ALIVE_CHECK */
12857
{
12858
if (rx_chk != _SUCCESS) {
12859
if (pmlmeext->retry == 0) {
12860
#ifdef DBG_EXPIRATION_CHK
12861
RTW_INFO("issue_probereq to trigger probersp, retry=%d\n", pmlmeext->retry);
12862
#endif
12863
issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
12864
issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
12865
issue_probereq_ex(padapter, &pmlmeinfo->network.Ssid, pmlmeinfo->network.MacAddress, 0, 0, 0, (from_timer ? 0 : 1));
12866
}
12867
}
12868
12869
if (tx_chk != _SUCCESS && pmlmeinfo->link_count++ == link_count_limit
12870
#ifdef CONFIG_MCC_MODE
12871
/* FW tx nulldata under MCC mode, we just check ap is alive */
12872
&& (!rtw_hal_check_mcc_status(padapter, MCC_STATUS_NEED_MCC))
12873
#endif /* CONFIG_MCC_MODE */
12874
) {
12875
#ifdef DBG_EXPIRATION_CHK
12876
RTW_INFO("%s issue_nulldata(%d)\n", __FUNCTION__, from_timer ? 1 : 0);
12877
#endif
12878
if (from_timer || rtw_mi_check_fwstate(padapter, _FW_UNDER_SURVEY))
12879
tx_chk = issue_nulldata(padapter, NULL, 1, 0, 0);
12880
else
12881
tx_chk = issue_nulldata(padapter, NULL, 0, 1, 1);
12882
}
12883
}
12884
12885
if (rx_chk == _FAIL) {
12886
pmlmeext->retry++;
12887
if (pmlmeext->retry > rx_chk_limit) {
12888
RTW_PRINT(FUNC_ADPT_FMT" disconnect or roaming\n",
12889
FUNC_ADPT_ARG(padapter));
12890
receive_disconnect(padapter, pmlmeinfo->network.MacAddress
12891
, WLAN_REASON_EXPIRATION_CHK, _FALSE);
12892
return;
12893
}
12894
} else
12895
pmlmeext->retry = 0;
12896
12897
if (tx_chk == _FAIL)
12898
pmlmeinfo->link_count %= (link_count_limit + 1);
12899
else {
12900
psta->sta_stats.last_tx_pkts = psta->sta_stats.tx_pkts;
12901
pmlmeinfo->link_count = 0;
12902
}
12903
12904
} /* end of if ((psta = rtw_get_stainfo(pstapriv, passoc_res->network.MacAddress)) != NULL) */
12905
12906
} else if (is_client_associated_to_ibss(padapter)) {
12907
_irqL irqL;
12908
_list *phead, *plist, dlist;
12909
12910
_rtw_init_listhead(&dlist);
12911
12912
_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12913
12914
for (i = 0; i < NUM_STA; i++) {
12915
12916
phead = &(pstapriv->sta_hash[i]);
12917
plist = get_next(phead);
12918
while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {
12919
psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);
12920
plist = get_next(plist);
12921
12922
if (is_broadcast_mac_addr(psta->cmn.mac_addr))
12923
continue;
12924
12925
if (chk_adhoc_peer_is_alive(psta) || !psta->expire_to)
12926
psta->expire_to = pstapriv->adhoc_expire_to;
12927
else
12928
psta->expire_to--;
12929
12930
if (psta->expire_to <= 0) {
12931
rtw_list_delete(&psta->list);
12932
rtw_list_insert_tail(&psta->list, &dlist);
12933
}
12934
}
12935
}
12936
12937
_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);
12938
12939
plist = get_next(&dlist);
12940
while (rtw_end_of_queue_search(&dlist, plist) == _FALSE) {
12941
psta = LIST_CONTAINOR(plist, struct sta_info, list);
12942
plist = get_next(plist);
12943
rtw_list_delete(&psta->list);
12944
RTW_INFO(FUNC_ADPT_FMT" ibss expire "MAC_FMT"\n"
12945
, FUNC_ADPT_ARG(padapter), MAC_ARG(psta->cmn.mac_addr));
12946
report_del_sta_event(padapter, psta->cmn.mac_addr, WLAN_REASON_EXPIRATION_CHK, from_timer ? _TRUE : _FALSE, _FALSE);
12947
}
12948
}
12949
12950
}
12951
12952
void survey_timer_hdl(void *ctx)
12953
{
12954
_adapter *padapter = (_adapter *)ctx;
12955
struct cmd_obj *cmd;
12956
struct sitesurvey_parm *psurveyPara;
12957
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
12958
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
12959
12960
if (mlmeext_scan_state(pmlmeext) > SCAN_DISABLE) {
12961
cmd = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
12962
if (cmd == NULL) {
12963
rtw_warn_on(1);
12964
goto exit;
12965
}
12966
12967
psurveyPara = (struct sitesurvey_parm *)rtw_zmalloc(sizeof(struct sitesurvey_parm));
12968
if (psurveyPara == NULL) {
12969
rtw_warn_on(1);
12970
rtw_mfree((unsigned char *)cmd, sizeof(struct cmd_obj));
12971
goto exit;
12972
}
12973
12974
init_h2fwcmd_w_parm_no_rsp(cmd, psurveyPara, GEN_CMD_CODE(_SiteSurvey));
12975
rtw_enqueue_cmd(pcmdpriv, cmd);
12976
}
12977
12978
exit:
12979
return;
12980
}
12981
12982
#ifdef CONFIG_RTW_REPEATER_SON
12983
/* 100ms pass, stop rson_scan */
12984
void rson_timer_hdl(void *ctx)
12985
{
12986
_adapter *padapter = (_adapter *)ctx;
12987
12988
rtw_rson_scan_wk_cmd(padapter, RSON_SCAN_DISABLE);
12989
}
12990
12991
#endif
12992
12993
void link_timer_hdl(void *ctx)
12994
{
12995
_adapter *padapter = (_adapter *)ctx;
12996
/* static unsigned int rx_pkt = 0; */
12997
/* static u64 tx_cnt = 0; */
12998
/* struct xmit_priv *pxmitpriv = &(padapter->xmitpriv); */
12999
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13000
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13001
/* struct sta_priv *pstapriv = &padapter->stapriv; */
13002
#ifdef CONFIG_RTW_80211R
13003
struct sta_priv *pstapriv = &padapter->stapriv;
13004
struct sta_info *psta = NULL;
13005
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13006
#endif
13007
13008
if (rtw_sta_linking_test_force_fail())
13009
RTW_INFO("rtw_sta_linking_test_force_fail\n");
13010
13011
if (pmlmeext->join_abort && pmlmeinfo->state != WIFI_FW_NULL_STATE) {
13012
RTW_INFO(FUNC_ADPT_FMT" join abort\n", FUNC_ADPT_ARG(padapter));
13013
pmlmeinfo->state = WIFI_FW_NULL_STATE;
13014
report_join_res(padapter, -4, WLAN_STATUS_UNSPECIFIED_FAILURE);
13015
goto exit;
13016
}
13017
13018
if (pmlmeinfo->state & WIFI_FW_AUTH_NULL) {
13019
RTW_INFO("link_timer_hdl:no beacon while connecting\n");
13020
pmlmeinfo->state = WIFI_FW_NULL_STATE;
13021
report_join_res(padapter, -3, WLAN_STATUS_UNSPECIFIED_FAILURE);
13022
} else if (pmlmeinfo->state & WIFI_FW_AUTH_STATE) {
13023
13024
#ifdef CONFIG_IOCTL_CFG80211
13025
if (rtw_sec_chk_auth_type(padapter, NL80211_AUTHTYPE_SAE))
13026
return;
13027
#endif /* CONFIG_IOCTL_CFG80211 */
13028
13029
/* re-auth timer */
13030
if (++pmlmeinfo->reauth_count > REAUTH_LIMIT) {
13031
/* if (pmlmeinfo->auth_algo != dot11AuthAlgrthm_Auto) */
13032
/* { */
13033
pmlmeinfo->state = 0;
13034
if (pmlmeinfo->auth_status) {
13035
report_join_res(padapter, -1, pmlmeinfo->auth_status);
13036
pmlmeinfo->auth_status = 0; /* reset */
13037
} else
13038
report_join_res(padapter, -1, WLAN_STATUS_UNSPECIFIED_FAILURE);
13039
return;
13040
/* } */
13041
/* else */
13042
/* { */
13043
/* pmlmeinfo->auth_algo = dot11AuthAlgrthm_Shared; */
13044
/* pmlmeinfo->reauth_count = 0; */
13045
/* } */
13046
}
13047
13048
RTW_INFO("link_timer_hdl: auth timeout and try again\n");
13049
pmlmeinfo->auth_seq = 1;
13050
issue_auth(padapter, NULL, 0);
13051
set_link_timer(pmlmeext, REAUTH_TO);
13052
} else if (pmlmeinfo->state & WIFI_FW_ASSOC_STATE) {
13053
/* re-assoc timer */
13054
if (++pmlmeinfo->reassoc_count > REASSOC_LIMIT) {
13055
pmlmeinfo->state = WIFI_FW_NULL_STATE;
13056
#ifdef CONFIG_RTW_80211R
13057
if (rtw_ft_roam(padapter)) {
13058
psta = rtw_get_stainfo(pstapriv, pmlmeinfo->network.MacAddress);
13059
if (psta)
13060
rtw_free_stainfo(padapter, psta);
13061
}
13062
#endif
13063
report_join_res(padapter, -2, WLAN_STATUS_UNSPECIFIED_FAILURE);
13064
return;
13065
}
13066
13067
#ifdef CONFIG_RTW_80211R
13068
if (rtw_ft_roam(padapter)) {
13069
RTW_INFO("link_timer_hdl: reassoc timeout and try again\n");
13070
issue_reassocreq(padapter);
13071
} else
13072
#endif
13073
{
13074
RTW_INFO("link_timer_hdl: assoc timeout and try again\n");
13075
issue_assocreq(padapter);
13076
}
13077
13078
set_link_timer(pmlmeext, REASSOC_TO);
13079
}
13080
13081
exit:
13082
return;
13083
}
13084
13085
void addba_timer_hdl(void *ctx)
13086
{
13087
struct sta_info *psta = (struct sta_info *)ctx;
13088
13089
#ifdef CONFIG_80211N_HT
13090
struct ht_priv *phtpriv;
13091
13092
if (!psta)
13093
return;
13094
13095
phtpriv = &psta->htpriv;
13096
13097
if ((phtpriv->ht_option == _TRUE) && (phtpriv->ampdu_enable == _TRUE)) {
13098
if (phtpriv->candidate_tid_bitmap)
13099
phtpriv->candidate_tid_bitmap = 0x0;
13100
13101
}
13102
#endif /* CONFIG_80211N_HT */
13103
}
13104
13105
#ifdef CONFIG_IEEE80211W
13106
void report_sta_timeout_event(_adapter *padapter, u8 *MacAddr, unsigned short reason)
13107
{
13108
struct cmd_obj *pcmd_obj;
13109
u8 *pevtcmd;
13110
u32 cmdsz;
13111
struct sta_info *psta;
13112
int mac_id;
13113
struct stadel_event *pdel_sta_evt;
13114
struct C2HEvent_Header *pc2h_evt_hdr;
13115
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13116
struct cmd_priv *pcmdpriv = &padapter->cmdpriv;
13117
13118
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13119
if (pcmd_obj == NULL)
13120
return;
13121
13122
cmdsz = (sizeof(struct stadel_event) + sizeof(struct C2HEvent_Header));
13123
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
13124
if (pevtcmd == NULL) {
13125
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
13126
return;
13127
}
13128
13129
_rtw_init_listhead(&pcmd_obj->list);
13130
13131
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
13132
pcmd_obj->cmdsz = cmdsz;
13133
pcmd_obj->parmbuf = pevtcmd;
13134
13135
pcmd_obj->rsp = NULL;
13136
pcmd_obj->rspsz = 0;
13137
13138
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
13139
pc2h_evt_hdr->len = sizeof(struct stadel_event);
13140
pc2h_evt_hdr->ID = GEN_EVT_CODE(_TimeoutSTA);
13141
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
13142
13143
pdel_sta_evt = (struct stadel_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
13144
_rtw_memcpy((unsigned char *)(&(pdel_sta_evt->macaddr)), MacAddr, ETH_ALEN);
13145
_rtw_memcpy((unsigned char *)(pdel_sta_evt->rsvd), (unsigned char *)(&reason), 2);
13146
13147
13148
psta = rtw_get_stainfo(&padapter->stapriv, MacAddr);
13149
if (psta)
13150
mac_id = (int)psta->cmn.mac_id;
13151
else
13152
mac_id = (-1);
13153
13154
pdel_sta_evt->mac_id = mac_id;
13155
13156
RTW_INFO("report_del_sta_event: delete STA, mac_id=%d\n", mac_id);
13157
13158
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
13159
13160
return;
13161
}
13162
13163
void clnt_sa_query_timeout(_adapter *padapter)
13164
{
13165
struct mlme_ext_priv *mlmeext = &(padapter->mlmeextpriv);
13166
struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
13167
13168
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(padapter));
13169
receive_disconnect(padapter, get_my_bssid(&(mlmeinfo->network)), WLAN_REASON_SA_QUERY_TIMEOUT, _FALSE);
13170
}
13171
13172
void sa_query_timer_hdl(void *ctx)
13173
{
13174
struct sta_info *psta = (struct sta_info *)ctx;
13175
_adapter *padapter = psta->padapter;
13176
_irqL irqL;
13177
struct sta_priv *pstapriv = &padapter->stapriv;
13178
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13179
13180
if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE &&
13181
check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
13182
clnt_sa_query_timeout(padapter);
13183
else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
13184
report_sta_timeout_event(padapter, psta->cmn.mac_addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
13185
}
13186
13187
#endif /* CONFIG_IEEE80211W */
13188
13189
#ifdef CONFIG_RTW_80211R
13190
void rtw_ft_update_bcn(_adapter *padapter, union recv_frame *precv_frame)
13191
{
13192
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13193
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13194
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
13195
u8 *pframe = precv_frame->u.hdr.rx_data;
13196
uint len = precv_frame->u.hdr.len;
13197
WLAN_BSSID_EX *pbss;
13198
13199
if (rtw_ft_chk_status(padapter,RTW_FT_ASSOCIATED_STA)
13200
&& (pmlmepriv->ft_roam.ft_updated_bcn == _FALSE)) {
13201
pbss = (WLAN_BSSID_EX*)rtw_malloc(sizeof(WLAN_BSSID_EX));
13202
if (pbss) {
13203
if (collect_bss_info(padapter, precv_frame, pbss) == _SUCCESS) {
13204
struct beacon_keys recv_beacon;
13205
13206
update_network(&(pmlmepriv->cur_network.network), pbss, padapter, _TRUE);
13207
13208
/* update bcn keys */
13209
if (rtw_get_bcn_keys(padapter, pframe, len, &recv_beacon) == _TRUE) {
13210
RTW_INFO("%s: beacon keys ready\n", __func__);
13211
_rtw_memcpy(&pmlmepriv->cur_beacon_keys,
13212
&recv_beacon, sizeof(recv_beacon));
13213
} else {
13214
RTW_ERR("%s: get beacon keys failed\n", __func__);
13215
_rtw_memset(&pmlmepriv->cur_beacon_keys, 0, sizeof(recv_beacon));
13216
}
13217
#ifdef CONFIG_BCN_CNT_CONFIRM_HDL
13218
pmlmepriv->new_beacon_cnts = 0;
13219
#endif
13220
}
13221
rtw_mfree((u8*)pbss, sizeof(WLAN_BSSID_EX));
13222
}
13223
13224
/* check the vendor of the assoc AP */
13225
pmlmeinfo->assoc_AP_vendor =
13226
check_assoc_AP(pframe+sizeof(struct rtw_ieee80211_hdr_3addr),
13227
(len - sizeof(struct rtw_ieee80211_hdr_3addr)));
13228
13229
/* update TSF Value */
13230
update_TSF(pmlmeext, pframe, len);
13231
pmlmeext->bcn_cnt = 0;
13232
pmlmeext->last_bcn_cnt = 0;
13233
pmlmepriv->ft_roam.ft_updated_bcn = _TRUE;
13234
}
13235
}
13236
13237
void rtw_ft_start_clnt_join(_adapter *padapter)
13238
{
13239
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
13240
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13241
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13242
struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam);
13243
13244
if (rtw_ft_otd_roam(padapter)) {
13245
pmlmeinfo->state = WIFI_FW_AUTH_SUCCESS | WIFI_FW_STATION_STATE;
13246
pft_roam->ft_event.ies =
13247
(pft_roam->ft_action + sizeof(struct rtw_ieee80211_hdr_3addr) + 16);
13248
pft_roam->ft_event.ies_len =
13249
(pft_roam->ft_action_len - sizeof(struct rtw_ieee80211_hdr_3addr));
13250
13251
/*Not support RIC*/
13252
pft_roam->ft_event.ric_ies = NULL;
13253
pft_roam->ft_event.ric_ies_len = 0;
13254
rtw_ft_report_evt(padapter);
13255
return;
13256
}
13257
13258
pmlmeinfo->state = WIFI_FW_AUTH_NULL | WIFI_FW_STATION_STATE;
13259
start_clnt_auth(padapter);
13260
}
13261
13262
u8 rtw_ft_update_rsnie(
13263
_adapter *padapter, u8 bwrite,
13264
struct pkt_attrib *pattrib, u8 **pframe)
13265
{
13266
struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam);
13267
u8 *pie;
13268
u32 len;
13269
13270
pie = rtw_get_ie(pft_roam->updated_ft_ies, EID_WPA2, &len,
13271
pft_roam->updated_ft_ies_len);
13272
13273
if (!bwrite)
13274
return (pie)?_SUCCESS:_FAIL;
13275
13276
if (pie) {
13277
*pframe = rtw_set_ie(((u8 *)*pframe), EID_WPA2, len,
13278
pie+2, &(pattrib->pktlen));
13279
} else
13280
return _FAIL;
13281
13282
return _SUCCESS;
13283
}
13284
13285
static u8 rtw_ft_update_mdie(
13286
_adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe)
13287
{
13288
struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam);
13289
u8 *pie, mdie[3];
13290
u32 len = 3;
13291
13292
if (rtw_ft_roam(padapter)) {
13293
if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _MDIE_,
13294
&len, pft_roam->updated_ft_ies_len))) {
13295
pie = (pie + 2); /* ignore md-id & length */
13296
} else
13297
return _FAIL;
13298
} else {
13299
*((u16 *)&mdie[0]) = pft_roam->mdid;
13300
mdie[2] = pft_roam->ft_cap;
13301
pie = &mdie[0];
13302
}
13303
13304
*pframe = rtw_set_ie(((u8 *)*pframe), _MDIE_, len , pie, &(pattrib->pktlen));
13305
return _SUCCESS;
13306
}
13307
13308
static u8 rtw_ft_update_ftie(
13309
_adapter *padapter, struct pkt_attrib *pattrib, u8 **pframe)
13310
{
13311
struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam);
13312
u8 *pie;
13313
u32 len;
13314
13315
if ((pie = rtw_get_ie(pft_roam->updated_ft_ies, _FTIE_, &len,
13316
pft_roam->updated_ft_ies_len)) != NULL) {
13317
*pframe = rtw_set_ie(*pframe, _FTIE_, len ,
13318
(pie+2), &(pattrib->pktlen));
13319
} else
13320
return _FAIL;
13321
13322
return _SUCCESS;
13323
}
13324
13325
void rtw_ft_build_auth_req_ies(_adapter *padapter,
13326
struct pkt_attrib *pattrib, u8 **pframe)
13327
{
13328
u8 ftie_append = _TRUE;
13329
13330
if (!pattrib || !(*pframe))
13331
return;
13332
13333
if (!rtw_ft_roam(padapter))
13334
return;
13335
13336
ftie_append = rtw_ft_update_rsnie(padapter, _TRUE, pattrib, pframe);
13337
rtw_ft_update_mdie(padapter, pattrib, pframe);
13338
if (ftie_append)
13339
rtw_ft_update_ftie(padapter, pattrib, pframe);
13340
}
13341
13342
void rtw_ft_build_assoc_req_ies(_adapter *padapter,
13343
u8 is_reassoc, struct pkt_attrib *pattrib, u8 **pframe)
13344
{
13345
if (!pattrib || !(*pframe))
13346
return;
13347
13348
if (rtw_ft_chk_flags(padapter, RTW_FT_PEER_EN))
13349
rtw_ft_update_mdie(padapter, pattrib, pframe);
13350
13351
if ((!is_reassoc) || (!rtw_ft_roam(padapter)))
13352
return;
13353
13354
if (rtw_ft_update_rsnie(padapter, _FALSE, pattrib, pframe))
13355
rtw_ft_update_ftie(padapter, pattrib, pframe);
13356
}
13357
13358
u8 rtw_ft_update_auth_rsp_ies(_adapter *padapter, u8 *pframe, u32 len)
13359
{
13360
u8 ret = _SUCCESS;
13361
u8 target_ap_addr[ETH_ALEN] = {0};
13362
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13363
struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam);
13364
13365
if (!rtw_ft_roam(padapter))
13366
return _FAIL;
13367
13368
/*rtw_ft_report_reassoc_evt already,
13369
* and waiting for cfg80211_rtw_update_ft_ies */
13370
if (rtw_ft_authed_sta(padapter))
13371
return ret;
13372
13373
if (!pframe || !len)
13374
return _FAIL;
13375
13376
rtw_buf_update(&pmlmepriv->auth_rsp,
13377
&pmlmepriv->auth_rsp_len, pframe, len);
13378
pft_roam->ft_event.ies =
13379
(pmlmepriv->auth_rsp + sizeof(struct rtw_ieee80211_hdr_3addr) + 6);
13380
pft_roam->ft_event.ies_len =
13381
(pmlmepriv->auth_rsp_len - sizeof(struct rtw_ieee80211_hdr_3addr) - 6);
13382
13383
/*Not support RIC*/
13384
pft_roam->ft_event.ric_ies = NULL;
13385
pft_roam->ft_event.ric_ies_len = 0;
13386
_rtw_memcpy(target_ap_addr, pmlmepriv->assoc_bssid, ETH_ALEN);
13387
rtw_ft_report_reassoc_evt(padapter, target_ap_addr);
13388
13389
return ret;
13390
}
13391
13392
static void rtw_ft_start_clnt_action(_adapter *padapter, u8 *pTargetAddr)
13393
{
13394
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13395
13396
rtw_ft_set_status(padapter, RTW_FT_REQUESTING_STA);
13397
rtw_ft_issue_action_req(padapter, pTargetAddr);
13398
_set_timer(&pmlmeext->ft_link_timer, REASSOC_TO);
13399
}
13400
13401
void rtw_ft_start_roam(_adapter *padapter, u8 *pTargetAddr)
13402
{
13403
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13404
13405
if (rtw_ft_otd_roam(padapter)) {
13406
rtw_ft_start_clnt_action(padapter, pTargetAddr);
13407
} else {
13408
/*wait a little time to retrieve packets buffered in the current ap while scan*/
13409
_set_timer(&pmlmeext->ft_roam_timer, 30);
13410
}
13411
}
13412
13413
void rtw_ft_issue_action_req(_adapter *padapter, u8 *pTargetAddr)
13414
{
13415
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13416
struct xmit_priv *pxmitpriv = &(padapter->xmitpriv);
13417
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
13418
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13419
struct xmit_frame *pmgntframe;
13420
struct rtw_ieee80211_hdr *pwlanhdr;
13421
struct pkt_attrib *pattrib;
13422
u8 *pframe;
13423
u8 category = RTW_WLAN_CATEGORY_FT;
13424
u8 action = RTW_WLAN_ACTION_FT_REQ;
13425
13426
pmgntframe = alloc_mgtxmitframe(pxmitpriv);
13427
if (pmgntframe == NULL)
13428
return;
13429
13430
pattrib = &pmgntframe->attrib;
13431
update_mgntframe_attrib(padapter, pattrib);
13432
_rtw_memset(pmgntframe->buf_addr, 0, WLANHDR_OFFSET + TXDESC_OFFSET);
13433
13434
pframe = (u8 *)(pmgntframe->buf_addr) + TXDESC_OFFSET;
13435
pwlanhdr = (struct rtw_ieee80211_hdr *)pframe;
13436
pwlanhdr->frame_ctl = 0;
13437
13438
_rtw_memcpy(pwlanhdr->addr1, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
13439
_rtw_memcpy(pwlanhdr->addr2, adapter_mac_addr(padapter), ETH_ALEN);
13440
_rtw_memcpy(pwlanhdr->addr3, get_my_bssid(&pmlmeinfo->network), ETH_ALEN);
13441
13442
SetSeqNum(pwlanhdr, pmlmeext->mgnt_seq);
13443
pmlmeext->mgnt_seq++;
13444
set_frame_sub_type(pframe, WIFI_ACTION);
13445
13446
pframe += sizeof(struct rtw_ieee80211_hdr_3addr);
13447
pattrib->pktlen = sizeof(struct rtw_ieee80211_hdr_3addr);
13448
13449
pframe = rtw_set_fixed_ie(pframe, 1, &(category), &(pattrib->pktlen));
13450
pframe = rtw_set_fixed_ie(pframe, 1, &(action), &(pattrib->pktlen));
13451
13452
_rtw_memcpy(pframe, adapter_mac_addr(padapter), ETH_ALEN);
13453
pframe += ETH_ALEN;
13454
pattrib->pktlen += ETH_ALEN;
13455
13456
_rtw_memcpy(pframe, pTargetAddr, ETH_ALEN);
13457
pframe += ETH_ALEN;
13458
pattrib->pktlen += ETH_ALEN;
13459
13460
rtw_ft_update_mdie(padapter, pattrib, &pframe);
13461
if (rtw_ft_update_rsnie(padapter, _TRUE, pattrib, &pframe))
13462
rtw_ft_update_ftie(padapter, pattrib, &pframe);
13463
13464
pattrib->last_txcmdsz = pattrib->pktlen;
13465
dump_mgntframe(padapter, pmgntframe);
13466
}
13467
13468
void rtw_ft_report_evt(_adapter *padapter)
13469
{
13470
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13471
struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam);
13472
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
13473
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13474
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)&(pmlmeinfo->network);
13475
struct cfg80211_ft_event_params ft_evt_parms;
13476
_irqL irqL;
13477
13478
_rtw_memset(&ft_evt_parms, 0, sizeof(ft_evt_parms));
13479
rtw_ft_update_stainfo(padapter, pnetwork);
13480
13481
if (!pnetwork)
13482
goto err_2;
13483
13484
ft_evt_parms.ies_len = pft_roam->ft_event.ies_len;
13485
ft_evt_parms.ies = rtw_zmalloc(ft_evt_parms.ies_len);
13486
if (ft_evt_parms.ies)
13487
_rtw_memcpy((void *)ft_evt_parms.ies, pft_roam->ft_event.ies, ft_evt_parms.ies_len);
13488
else
13489
goto err_2;
13490
13491
ft_evt_parms.target_ap = rtw_zmalloc(ETH_ALEN);
13492
if (ft_evt_parms.target_ap)
13493
_rtw_memcpy((void *)ft_evt_parms.target_ap, pnetwork->MacAddress, ETH_ALEN);
13494
else
13495
goto err_1;
13496
13497
ft_evt_parms.ric_ies = pft_roam->ft_event.ric_ies;
13498
ft_evt_parms.ric_ies_len = pft_roam->ft_event.ric_ies_len;
13499
13500
rtw_ft_lock_set_status(padapter, RTW_FT_AUTHENTICATED_STA, &irqL);
13501
rtw_cfg80211_ft_event(padapter, &ft_evt_parms);
13502
RTW_INFO("FT: rtw_ft_report_evt\n");
13503
rtw_mfree((u8 *)pft_roam->ft_event.target_ap, ETH_ALEN);
13504
err_1:
13505
rtw_mfree((u8 *)ft_evt_parms.ies, ft_evt_parms.ies_len);
13506
err_2:
13507
return;
13508
}
13509
13510
void rtw_ft_report_reassoc_evt(_adapter *padapter, u8 *pMacAddr)
13511
{
13512
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
13513
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
13514
struct cmd_obj *pcmd_obj = NULL;
13515
struct stassoc_event *passoc_sta_evt = NULL;
13516
struct C2HEvent_Header *pc2h_evt_hdr = NULL;
13517
u8 *pevtcmd = NULL;
13518
u32 cmdsz = 0;
13519
13520
pcmd_obj = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
13521
if (pcmd_obj == NULL)
13522
return;
13523
13524
cmdsz = (sizeof(struct stassoc_event) + sizeof(struct C2HEvent_Header));
13525
pevtcmd = (u8 *)rtw_zmalloc(cmdsz);
13526
if (pevtcmd == NULL) {
13527
rtw_mfree((u8 *)pcmd_obj, sizeof(struct cmd_obj));
13528
return;
13529
}
13530
13531
_rtw_init_listhead(&pcmd_obj->list);
13532
pcmd_obj->cmdcode = GEN_CMD_CODE(_Set_MLME_EVT);
13533
pcmd_obj->cmdsz = cmdsz;
13534
pcmd_obj->parmbuf = pevtcmd;
13535
pcmd_obj->rsp = NULL;
13536
pcmd_obj->rspsz = 0;
13537
13538
pc2h_evt_hdr = (struct C2HEvent_Header *)(pevtcmd);
13539
pc2h_evt_hdr->len = sizeof(struct stassoc_event);
13540
pc2h_evt_hdr->ID = GEN_EVT_CODE(_FT_REASSOC);
13541
pc2h_evt_hdr->seq = ATOMIC_INC_RETURN(&pmlmeext->event_seq);
13542
13543
passoc_sta_evt = (struct stassoc_event *)(pevtcmd + sizeof(struct C2HEvent_Header));
13544
_rtw_memcpy((unsigned char *)(&(passoc_sta_evt->macaddr)), pMacAddr, ETH_ALEN);
13545
rtw_enqueue_cmd(pcmdpriv, pcmd_obj);
13546
}
13547
13548
void rtw_ft_link_timer_hdl(void *ctx)
13549
{
13550
_adapter *padapter = (_adapter *)ctx;
13551
struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
13552
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13553
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13554
struct ft_roam_info *pft_roam = &(pmlmepriv->ft_roam);
13555
13556
if (rtw_ft_chk_status(padapter, RTW_FT_REQUESTING_STA)) {
13557
if (pft_roam->ft_req_retry_cnt < RTW_FT_ACTION_REQ_LMT) {
13558
pft_roam->ft_req_retry_cnt++;
13559
rtw_ft_issue_action_req(padapter, (u8 *)pmlmepriv->roam_network->network.MacAddress);
13560
_set_timer(&pmlmeext->ft_link_timer, REASSOC_TO);
13561
} else {
13562
pft_roam->ft_req_retry_cnt = 0;
13563
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS)
13564
rtw_ft_set_status(padapter, RTW_FT_ASSOCIATED_STA);
13565
else
13566
rtw_ft_reset_status(padapter);
13567
}
13568
}
13569
}
13570
13571
void rtw_ft_roam_timer_hdl(void *ctx)
13572
{
13573
_adapter *padapter = (_adapter *)ctx;
13574
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
13575
13576
receive_disconnect(padapter, pmlmepriv->cur_network.network.MacAddress
13577
, WLAN_REASON_ACTIVE_ROAM, _FALSE);
13578
}
13579
13580
void rtw_ft_roam_status_reset(_adapter *padapter)
13581
{
13582
struct ft_roam_info *pft_roam = &(padapter->mlmepriv.ft_roam);
13583
13584
if ((rtw_to_roam(padapter) > 0) &&
13585
(!rtw_ft_chk_status(padapter, RTW_FT_REQUESTED_STA))) {
13586
rtw_ft_reset_status(padapter);
13587
}
13588
13589
padapter->mlmepriv.ft_roam.ft_updated_bcn = _FALSE;
13590
}
13591
#endif
13592
13593
u8 NULL_hdl(_adapter *padapter, u8 *pbuf)
13594
{
13595
return H2C_SUCCESS;
13596
}
13597
13598
#ifdef CONFIG_AUTO_AP_MODE
13599
void rtw_auto_ap_rx_msg_dump(_adapter *padapter, union recv_frame *precv_frame, u8 *ehdr_pos)
13600
{
13601
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
13602
struct sta_info *psta = precv_frame->u.hdr.psta;
13603
struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos;
13604
13605
RTW_INFO("eth rx: got eth_type=0x%x\n", ntohs(ehdr->h_proto));
13606
13607
if (psta && psta->isrc && psta->pid > 0) {
13608
u16 rx_pid;
13609
13610
rx_pid = *(u16 *)(ehdr_pos + ETH_HLEN);
13611
13612
RTW_INFO("eth rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n",
13613
rx_pid, MAC_ARG(psta->cmn.mac_addr), psta->pid);
13614
13615
if (rx_pid == psta->pid) {
13616
int i;
13617
u16 len = *(u16 *)(ehdr_pos + ETH_HLEN + 2);
13618
/* u16 ctrl_type = *(u16 *)(ehdr_pos + ETH_HLEN + 4); */
13619
13620
/* RTW_INFO("eth, RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type); */
13621
RTW_INFO("eth, RC: len=0x%x\n", len);
13622
13623
for (i = 0; i < len; i++)
13624
RTW_INFO("0x%x\n", *(ehdr_pos + ETH_HLEN + 4 + i));
13625
/* RTW_INFO("0x%x\n", *(ehdr_pos + ETH_HLEN + 6 + i)); */
13626
13627
RTW_INFO("eth, RC-end\n");
13628
}
13629
}
13630
13631
}
13632
13633
void rtw_start_auto_ap(_adapter *adapter)
13634
{
13635
RTW_INFO("%s\n", __FUNCTION__);
13636
13637
rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11APMode, 0);
13638
13639
rtw_setopmode_cmd(adapter, Ndis802_11APMode, RTW_CMDF_WAIT_ACK);
13640
}
13641
13642
static int rtw_auto_ap_start_beacon(_adapter *adapter)
13643
{
13644
int ret = 0;
13645
u8 *pbuf = NULL;
13646
uint len;
13647
u8 supportRate[16];
13648
int sz = 0, rateLen;
13649
u8 *ie;
13650
u8 wireless_mode, oper_channel;
13651
u8 ssid[3] = {0}; /* hidden ssid */
13652
u32 ssid_len = sizeof(ssid);
13653
struct mlme_priv *pmlmepriv = &(adapter->mlmepriv);
13654
13655
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) != _TRUE)
13656
return -EINVAL;
13657
13658
13659
len = 128;
13660
pbuf = rtw_zmalloc(len);
13661
if (!pbuf)
13662
return -ENOMEM;
13663
13664
13665
/* generate beacon */
13666
ie = pbuf;
13667
13668
/* timestamp will be inserted by hardware */
13669
sz += 8;
13670
ie += sz;
13671
13672
/* beacon interval : 2bytes */
13673
*(u16 *)ie = cpu_to_le16((u16)100); /* BCN_INTERVAL=100; */
13674
sz += 2;
13675
ie += 2;
13676
13677
/* capability info */
13678
*(u16 *)ie = 0;
13679
*(u16 *)ie |= cpu_to_le16(cap_ESS);
13680
*(u16 *)ie |= cpu_to_le16(cap_ShortPremble);
13681
/* *(u16*)ie |= cpu_to_le16(cap_Privacy); */
13682
sz += 2;
13683
ie += 2;
13684
13685
/* SSID */
13686
ie = rtw_set_ie(ie, _SSID_IE_, ssid_len, ssid, &sz);
13687
13688
/* supported rates */
13689
wireless_mode = (WIRELESS_11BG_24N & padapter->registrypriv.wireless_mode);
13690
rtw_set_supported_rate(supportRate, wireless_mode);
13691
rateLen = rtw_get_rateset_len(supportRate);
13692
if (rateLen > 8)
13693
ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, 8, supportRate, &sz);
13694
else
13695
ie = rtw_set_ie(ie, _SUPPORTEDRATES_IE_, rateLen, supportRate, &sz);
13696
13697
13698
/* DS parameter set */
13699
if (rtw_mi_check_status(adapter, MI_LINKED))
13700
oper_channel = rtw_mi_get_union_chan(adapter);
13701
else
13702
oper_channel = adapter_to_dvobj(adapter)->oper_channel;
13703
13704
ie = rtw_set_ie(ie, _DSSET_IE_, 1, &oper_channel, &sz);
13705
13706
/* ext supported rates */
13707
if (rateLen > 8)
13708
ie = rtw_set_ie(ie, _EXT_SUPPORTEDRATES_IE_, (rateLen - 8), (supportRate + 8), &sz);
13709
13710
RTW_INFO("%s, start auto ap beacon sz=%d\n", __FUNCTION__, sz);
13711
13712
/* lunch ap mode & start to issue beacon */
13713
if (rtw_check_beacon_data(adapter, pbuf, sz) == _SUCCESS) {
13714
13715
} else
13716
ret = -EINVAL;
13717
13718
13719
rtw_mfree(pbuf, len);
13720
13721
return ret;
13722
13723
}
13724
#endif/* CONFIG_AUTO_AP_MODE */
13725
13726
#ifdef CONFIG_AP_MODE
13727
u8 stop_ap_hdl(_adapter *adapter)
13728
{
13729
RTW_INFO(FUNC_ADPT_FMT"\n", FUNC_ADPT_ARG(adapter));
13730
13731
rtw_set_802_11_infrastructure_mode(adapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
13732
rtw_setopmode_cmd(adapter, Ndis802_11Infrastructure, RTW_CMDF_DIRECTLY);
13733
13734
return H2C_SUCCESS;
13735
}
13736
#endif
13737
13738
u8 setopmode_hdl(_adapter *padapter, u8 *pbuf)
13739
{
13740
u8 type;
13741
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13742
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13743
struct setopmode_parm *psetop = (struct setopmode_parm *)pbuf;
13744
13745
if (psetop->mode == Ndis802_11APMode
13746
|| psetop->mode == Ndis802_11_mesh
13747
) {
13748
pmlmeinfo->state = WIFI_FW_AP_STATE;
13749
type = _HW_STATE_AP_;
13750
} else if (psetop->mode == Ndis802_11Infrastructure) {
13751
pmlmeinfo->state &= ~(BIT(0) | BIT(1)); /* clear state */
13752
pmlmeinfo->state |= WIFI_FW_STATION_STATE;/* set to STATION_STATE */
13753
type = _HW_STATE_STATION_;
13754
} else if (psetop->mode == Ndis802_11IBSS)
13755
type = _HW_STATE_ADHOC_;
13756
else if (psetop->mode == Ndis802_11Monitor)
13757
type = _HW_STATE_MONITOR_;
13758
else
13759
type = _HW_STATE_NOLINK_;
13760
13761
#ifdef CONFIG_AP_PORT_SWAP
13762
rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, (u8 *)(&type));
13763
#endif
13764
13765
rtw_hal_set_hwreg(padapter, HW_VAR_SET_OPMODE, (u8 *)(&type));
13766
13767
#ifdef CONFIG_AUTO_AP_MODE
13768
if (psetop->mode == Ndis802_11APMode)
13769
rtw_auto_ap_start_beacon(padapter);
13770
#endif
13771
13772
if (rtw_port_switch_chk(padapter) == _TRUE) {
13773
rtw_hal_set_hwreg(padapter, HW_VAR_PORT_SWITCH, NULL);
13774
13775
if (psetop->mode == Ndis802_11APMode)
13776
adapter_to_pwrctl(padapter)->fw_psmode_iface_id = 0xff; /* ap mode won't dowload rsvd pages */
13777
else if (psetop->mode == Ndis802_11Infrastructure) {
13778
#ifdef CONFIG_LPS
13779
_adapter *port0_iface = dvobj_get_port0_adapter(adapter_to_dvobj(padapter));
13780
if (port0_iface)
13781
rtw_lps_ctrl_wk_cmd(port0_iface, LPS_CTRL_CONNECT, RTW_CMDF_DIRECTLY);
13782
#endif
13783
}
13784
}
13785
13786
#ifdef CONFIG_BT_COEXIST
13787
if (psetop->mode == Ndis802_11APMode
13788
|| psetop->mode == Ndis802_11_mesh
13789
|| psetop->mode == Ndis802_11Monitor
13790
) {
13791
/* Do this after port switch to */
13792
/* prevent from downloading rsvd page to wrong port */
13793
rtw_btcoex_MediaStatusNotify(padapter, 1); /* connect */
13794
}
13795
#endif /* CONFIG_BT_COEXIST */
13796
13797
return H2C_SUCCESS;
13798
13799
}
13800
13801
u8 createbss_hdl(_adapter *padapter, u8 *pbuf)
13802
{
13803
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13804
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13805
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13806
WLAN_BSSID_EX *pdev_network = &padapter->registrypriv.dev_network;
13807
struct createbss_parm *parm = (struct createbss_parm *)pbuf;
13808
u8 ret = H2C_SUCCESS;
13809
/* u8 initialgain; */
13810
13811
#ifdef CONFIG_AP_MODE
13812
if ((parm->req_ch == 0 && pmlmeinfo->state == WIFI_FW_AP_STATE)
13813
|| parm->req_ch != 0
13814
) {
13815
start_bss_network(padapter, parm);
13816
goto exit;
13817
}
13818
#endif
13819
13820
/* below is for ad-hoc master */
13821
if (parm->adhoc) {
13822
rtw_warn_on(pdev_network->InfrastructureMode != Ndis802_11IBSS);
13823
rtw_joinbss_reset(padapter);
13824
13825
pmlmeext->cur_bwmode = CHANNEL_WIDTH_20;
13826
pmlmeext->cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
13827
pmlmeinfo->ERP_enable = 0;
13828
pmlmeinfo->WMM_enable = 0;
13829
pmlmeinfo->HT_enable = 0;
13830
pmlmeinfo->HT_caps_enable = 0;
13831
pmlmeinfo->HT_info_enable = 0;
13832
pmlmeinfo->agg_enable_bitmap = 0;
13833
pmlmeinfo->candidate_tid_bitmap = 0;
13834
13835
/* cancel link timer */
13836
_cancel_timer_ex(&pmlmeext->link_timer);
13837
13838
/* clear CAM */
13839
flush_all_cam_entry(padapter);
13840
13841
pdev_network->Length = get_WLAN_BSSID_EX_sz(pdev_network);
13842
_rtw_memcpy(pnetwork, pdev_network, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13843
pnetwork->IELength = pdev_network->IELength;
13844
13845
if (pnetwork->IELength > MAX_IE_SZ) {
13846
ret = H2C_PARAMETERS_ERROR;
13847
goto ibss_post_hdl;
13848
}
13849
13850
_rtw_memcpy(pnetwork->IEs, pdev_network->IEs, pnetwork->IELength);
13851
start_create_ibss(padapter);
13852
} else {
13853
rtw_warn_on(1);
13854
ret = H2C_PARAMETERS_ERROR;
13855
}
13856
13857
ibss_post_hdl:
13858
rtw_create_ibss_post_hdl(padapter, ret);
13859
13860
exit:
13861
return ret;
13862
}
13863
13864
u8 join_cmd_hdl(_adapter *padapter, u8 *pbuf)
13865
{
13866
u8 join_type;
13867
PNDIS_802_11_VARIABLE_IEs pIE;
13868
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
13869
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
13870
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
13871
#ifdef CONFIG_ANTENNA_DIVERSITY
13872
struct joinbss_parm *pparm = (struct joinbss_parm *)pbuf;
13873
#endif /* CONFIG_ANTENNA_DIVERSITY */
13874
u32 i;
13875
/* u8 initialgain; */
13876
/* u32 acparm; */
13877
u8 u_ch, u_bw, u_offset;
13878
u8 doiqk = _FALSE;
13879
13880
/* check already connecting to AP or not */
13881
if (pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) {
13882
if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13883
issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
13884
pmlmeinfo->state = WIFI_FW_NULL_STATE;
13885
13886
/* clear CAM */
13887
flush_all_cam_entry(padapter);
13888
13889
_cancel_timer_ex(&pmlmeext->link_timer);
13890
13891
/* set MSR to nolink->infra. mode */
13892
/* Set_MSR(padapter, _HW_STATE_NOLINK_); */
13893
Set_MSR(padapter, _HW_STATE_STATION_);
13894
13895
13896
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_DISCONNECT, 0);
13897
if (pmlmeinfo->state & WIFI_FW_STATION_STATE)
13898
rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_DISCONNECTED);
13899
}
13900
13901
#ifdef CONFIG_ANTENNA_DIVERSITY
13902
rtw_antenna_select_cmd(padapter, pparm->network.PhyInfo.Optimum_antenna, _FALSE);
13903
#endif
13904
13905
#ifdef CONFIG_WAPI_SUPPORT
13906
rtw_wapi_clear_all_cam_entry(padapter);
13907
#endif
13908
13909
rtw_joinbss_reset(padapter);
13910
13911
pmlmeinfo->ERP_enable = 0;
13912
pmlmeinfo->WMM_enable = 0;
13913
pmlmeinfo->HT_enable = 0;
13914
pmlmeinfo->HT_caps_enable = 0;
13915
pmlmeinfo->HT_info_enable = 0;
13916
pmlmeinfo->agg_enable_bitmap = 0;
13917
pmlmeinfo->candidate_tid_bitmap = 0;
13918
pmlmeinfo->bwmode_updated = _FALSE;
13919
/* pmlmeinfo->assoc_AP_vendor = HT_IOT_PEER_MAX; */
13920
pmlmeinfo->VHT_enable = 0;
13921
#ifdef ROKU_PRIVATE
13922
pmlmeinfo->ht_vht_received = 0;
13923
_rtw_memset(pmlmeinfo->SupportedRates_infra_ap, 0, NDIS_802_11_LENGTH_RATES_EX);
13924
#endif /* ROKU_PRIVATE */
13925
_rtw_memcpy(pnetwork, pbuf, FIELD_OFFSET(WLAN_BSSID_EX, IELength));
13926
pnetwork->IELength = ((WLAN_BSSID_EX *)pbuf)->IELength;
13927
13928
if (pnetwork->IELength > MAX_IE_SZ) /* Check pbuf->IELength */
13929
return H2C_PARAMETERS_ERROR;
13930
13931
if (pnetwork->IELength < 2) {
13932
report_join_res(padapter, (-4), WLAN_STATUS_UNSPECIFIED_FAILURE);
13933
return H2C_SUCCESS;
13934
}
13935
_rtw_memcpy(pnetwork->IEs, ((WLAN_BSSID_EX *)pbuf)->IEs, pnetwork->IELength);
13936
13937
pmlmeinfo->bcn_interval = get_beacon_interval(pnetwork);
13938
13939
/* Check AP vendor to move rtw_joinbss_cmd() */
13940
/* pmlmeinfo->assoc_AP_vendor = check_assoc_AP(pnetwork->IEs, pnetwork->IELength); */
13941
13942
/* sizeof(NDIS_802_11_FIXED_IEs) */
13943
for (i = _FIXED_IE_LENGTH_ ; i < pnetwork->IELength - 2 ;) {
13944
pIE = (PNDIS_802_11_VARIABLE_IEs)(pnetwork->IEs + i);
13945
13946
switch (pIE->ElementID) {
13947
case _VENDOR_SPECIFIC_IE_: /* Get WMM IE. */
13948
if (_rtw_memcmp(pIE->data, WMM_OUI, 4))
13949
WMM_param_handler(padapter, pIE);
13950
break;
13951
13952
#ifdef CONFIG_80211N_HT
13953
case _HT_CAPABILITY_IE_: /* Get HT Cap IE. */
13954
pmlmeinfo->HT_caps_enable = 1;
13955
break;
13956
13957
case _HT_EXTRA_INFO_IE_: /* Get HT Info IE. */
13958
pmlmeinfo->HT_info_enable = 1;
13959
break;
13960
#endif /* CONFIG_80211N_HT */
13961
13962
#ifdef CONFIG_80211AC_VHT
13963
case EID_VHTCapability: /* Get VHT Cap IE. */
13964
pmlmeinfo->VHT_enable = 1;
13965
break;
13966
13967
case EID_VHTOperation: /* Get VHT Operation IE. */
13968
break;
13969
#endif /* CONFIG_80211AC_VHT */
13970
default:
13971
break;
13972
}
13973
13974
i += (pIE->Length + 2);
13975
}
13976
13977
rtw_bss_get_chbw(pnetwork
13978
, &pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset, 1, 1);
13979
13980
rtw_adjust_chbw(padapter, pmlmeext->cur_channel, &pmlmeext->cur_bwmode, &pmlmeext->cur_ch_offset);
13981
13982
#if 0
13983
if (padapter->registrypriv.wifi_spec) {
13984
/* for WiFi test, follow WMM test plan spec */
13985
acparm = 0x002F431C; /* VO */
13986
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
13987
acparm = 0x005E541C; /* VI */
13988
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
13989
acparm = 0x0000A525; /* BE */
13990
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13991
acparm = 0x0000A549; /* BK */
13992
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
13993
13994
/* for WiFi test, mixed mode with intel STA under bg mode throughput issue */
13995
if (padapter->mlmepriv.htpriv.ht_option == _FALSE) {
13996
acparm = 0x00004320;
13997
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
13998
}
13999
} else {
14000
acparm = 0x002F3217; /* VO */
14001
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VO, (u8 *)(&acparm));
14002
acparm = 0x005E4317; /* VI */
14003
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_VI, (u8 *)(&acparm));
14004
acparm = 0x00105320; /* BE */
14005
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BE, (u8 *)(&acparm));
14006
acparm = 0x0000A444; /* BK */
14007
rtw_hal_set_hwreg(padapter, HW_VAR_AC_PARAM_BK, (u8 *)(&acparm));
14008
}
14009
#endif
14010
14011
/* check channel, bandwidth, offset and switch */
14012
if (rtw_chk_start_clnt_join(padapter, &u_ch, &u_bw, &u_offset) == _FAIL) {
14013
report_join_res(padapter, (-4), WLAN_STATUS_UNSPECIFIED_FAILURE);
14014
return H2C_SUCCESS;
14015
}
14016
14017
/* disable dynamic functions, such as high power, DIG */
14018
/*rtw_phydm_func_disable_all(padapter);*/
14019
14020
/* config the initial gain under linking, need to write the BB registers */
14021
/* initialgain = 0x1E; */
14022
/*rtw_hal_set_odm_var(padapter, HAL_ODM_INITIAL_GAIN, &initialgain, _FALSE);*/
14023
14024
rtw_hal_set_hwreg(padapter, HW_VAR_BSSID, pmlmeinfo->network.MacAddress);
14025
if (MLME_IS_STA(padapter))
14026
rtw_hal_rcr_set_chk_bssid(padapter, MLME_STA_CONNECTING);
14027
else
14028
rtw_hal_rcr_set_chk_bssid(padapter, MLME_ADHOC_STARTED);
14029
14030
join_type = 0;
14031
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_JOIN, (u8 *)(&join_type));
14032
14033
doiqk = _TRUE;
14034
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
14035
14036
set_channel_bwmode(padapter, u_ch, u_offset, u_bw);
14037
rtw_mi_update_union_chan_inf(padapter, u_ch, u_offset, u_bw);
14038
14039
doiqk = _FALSE;
14040
rtw_hal_set_hwreg(padapter , HW_VAR_DO_IQK , &doiqk);
14041
14042
/* cancel link timer */
14043
_cancel_timer_ex(&pmlmeext->link_timer);
14044
14045
start_clnt_join(padapter);
14046
14047
return H2C_SUCCESS;
14048
14049
}
14050
14051
u8 disconnect_hdl(_adapter *padapter, unsigned char *pbuf)
14052
{
14053
#ifdef CONFIG_DFS
14054
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14055
#endif
14056
struct disconnect_parm *param = (struct disconnect_parm *)pbuf;
14057
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14058
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14059
WLAN_BSSID_EX *pnetwork = (WLAN_BSSID_EX *)(&(pmlmeinfo->network));
14060
u8 val8;
14061
14062
if (is_client_associated_to_ap(padapter)
14063
#ifdef CONFIG_DFS
14064
&& !IS_RADAR_DETECTED(rfctl) && !rfctl->csa_ch
14065
#endif
14066
) {
14067
#ifdef CONFIG_PLATFORM_ROCKCHIPS
14068
/* To avoid connecting to AP fail during resume process, change retry count from 5 to 1 */
14069
issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, 1, 100);
14070
#else
14071
issue_deauth_ex(padapter, pnetwork->MacAddress, WLAN_REASON_DEAUTH_LEAVING, param->deauth_timeout_ms / 100, 100);
14072
#endif /* CONFIG_PLATFORM_ROCKCHIPS */
14073
}
14074
14075
#ifndef CONFIG_SUPPORT_MULTI_BCN
14076
if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
14077
/* Stop BCN */
14078
val8 = 0;
14079
rtw_hal_set_hwreg(padapter, HW_VAR_BCN_FUNC, (u8 *)(&val8));
14080
}
14081
#endif
14082
14083
rtw_mlmeext_disconnect(padapter);
14084
14085
rtw_free_uc_swdec_pending_queue(padapter);
14086
14087
rtw_sta_mstatus_report(padapter);
14088
14089
return H2C_SUCCESS;
14090
}
14091
14092
static const char *const _scan_state_str[] = {
14093
"SCAN_DISABLE",
14094
"SCAN_START",
14095
"SCAN_PS_ANNC_WAIT",
14096
"SCAN_ENTER",
14097
"SCAN_PROCESS",
14098
"SCAN_BACKING_OP",
14099
"SCAN_BACK_OP",
14100
"SCAN_LEAVING_OP",
14101
"SCAN_LEAVE_OP",
14102
"SCAN_SW_ANTDIV_BL",
14103
"SCAN_TO_P2P_LISTEN",
14104
"SCAN_P2P_LISTEN",
14105
"SCAN_COMPLETE",
14106
"SCAN_STATE_MAX",
14107
};
14108
14109
const char *scan_state_str(u8 state)
14110
{
14111
state = (state >= SCAN_STATE_MAX) ? SCAN_STATE_MAX : state;
14112
return _scan_state_str[state];
14113
}
14114
14115
static bool scan_abort_hdl(_adapter *adapter)
14116
{
14117
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14118
struct ss_res *ss = &pmlmeext->sitesurvey_res;
14119
#ifdef CONFIG_P2P
14120
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14121
#endif
14122
bool ret = _FALSE;
14123
14124
if (pmlmeext->scan_abort == _TRUE) {
14125
#ifdef CONFIG_P2P
14126
if (!rtw_p2p_chk_state(&adapter->wdinfo, P2P_STATE_NONE)) {
14127
rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_MAX);
14128
ss->channel_idx = 3;
14129
RTW_INFO("%s idx:%d, cnt:%u\n", __FUNCTION__
14130
, ss->channel_idx
14131
, pwdinfo->find_phase_state_exchange_cnt
14132
);
14133
} else
14134
#endif
14135
{
14136
ss->channel_idx = ss->ch_num;
14137
RTW_INFO("%s idx:%d\n", __FUNCTION__
14138
, ss->channel_idx
14139
);
14140
}
14141
pmlmeext->scan_abort = _FALSE;
14142
ret = _TRUE;
14143
}
14144
14145
return ret;
14146
}
14147
14148
u8 rtw_scan_sparse(_adapter *adapter, struct rtw_ieee80211_channel *ch, u8 ch_num)
14149
{
14150
/* interval larger than this is treated as backgroud scan */
14151
#ifndef RTW_SCAN_SPARSE_BG_INTERVAL_MS
14152
#define RTW_SCAN_SPARSE_BG_INTERVAL_MS 12000
14153
#endif
14154
14155
#ifndef RTW_SCAN_SPARSE_CH_NUM_MIRACAST
14156
#define RTW_SCAN_SPARSE_CH_NUM_MIRACAST 1
14157
#endif
14158
#ifndef RTW_SCAN_SPARSE_CH_NUM_BG
14159
#define RTW_SCAN_SPARSE_CH_NUM_BG 4
14160
#endif
14161
#ifdef CONFIG_LAYER2_ROAMING
14162
#ifndef RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE
14163
#define RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE 1
14164
#endif
14165
#endif
14166
14167
#define SCAN_SPARSE_CH_NUM_INVALID 255
14168
14169
static u8 token = 255;
14170
u32 interval;
14171
bool busy_traffic = _FALSE;
14172
bool miracast_enabled = _FALSE;
14173
bool bg_scan = _FALSE;
14174
u8 max_allow_ch = SCAN_SPARSE_CH_NUM_INVALID;
14175
u8 scan_division_num;
14176
u8 ret_num = ch_num;
14177
struct registry_priv *regsty = dvobj_to_regsty(adapter_to_dvobj(adapter));
14178
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14179
14180
if (regsty->wifi_spec)
14181
goto exit;
14182
14183
/* assume ch_num > 6 is normal scan */
14184
if (ch_num <= 6)
14185
goto exit;
14186
14187
if (mlmeext->last_scan_time == 0)
14188
mlmeext->last_scan_time = rtw_get_current_time();
14189
14190
interval = rtw_get_passing_time_ms(mlmeext->last_scan_time);
14191
14192
14193
if (rtw_mi_busy_traffic_check(adapter, _FALSE))
14194
busy_traffic = _TRUE;
14195
14196
if (rtw_mi_check_miracast_enabled(adapter))
14197
miracast_enabled = _TRUE;
14198
14199
if (interval > RTW_SCAN_SPARSE_BG_INTERVAL_MS)
14200
bg_scan = _TRUE;
14201
14202
/* max_allow_ch by conditions*/
14203
14204
#if RTW_SCAN_SPARSE_MIRACAST
14205
if (miracast_enabled == _TRUE && busy_traffic == _TRUE)
14206
max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_MIRACAST);
14207
#endif
14208
14209
#if RTW_SCAN_SPARSE_BG
14210
if (bg_scan == _TRUE)
14211
max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_BG);
14212
#endif
14213
14214
#if defined(CONFIG_LAYER2_ROAMING) && defined(RTW_SCAN_SPARSE_ROAMING_ACTIVE)
14215
if (rtw_chk_roam_flags(adapter, RTW_ROAM_ACTIVE)) {
14216
if (busy_traffic == _TRUE && adapter->mlmepriv.need_to_roam == _TRUE)
14217
max_allow_ch = rtw_min(max_allow_ch, RTW_SCAN_SPARSE_CH_NUM_ROAMING_ACTIVE);
14218
}
14219
#endif
14220
14221
14222
if (max_allow_ch != SCAN_SPARSE_CH_NUM_INVALID) {
14223
int i;
14224
int k = 0;
14225
14226
scan_division_num = (ch_num / max_allow_ch) + ((ch_num % max_allow_ch) ? 1 : 0);
14227
token = (token + 1) % scan_division_num;
14228
14229
if (0)
14230
RTW_INFO("scan_division_num:%u, token:%u\n", scan_division_num, token);
14231
14232
for (i = 0; i < ch_num; i++) {
14233
if (ch[i].hw_value && (i % scan_division_num) == token
14234
) {
14235
if (i != k)
14236
_rtw_memcpy(&ch[k], &ch[i], sizeof(struct rtw_ieee80211_channel));
14237
k++;
14238
}
14239
}
14240
14241
_rtw_memset(&ch[k], 0, sizeof(struct rtw_ieee80211_channel));
14242
14243
ret_num = k;
14244
mlmeext->last_scan_time = rtw_get_current_time();
14245
}
14246
14247
exit:
14248
return ret_num;
14249
}
14250
14251
#ifdef CONFIG_SCAN_BACKOP
14252
u8 rtw_scan_backop_decision(_adapter *adapter)
14253
{
14254
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14255
struct mi_state mstate;
14256
u8 backop_flags = 0;
14257
14258
rtw_mi_status(adapter, &mstate);
14259
14260
if ((MSTATE_STA_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN))
14261
|| (MSTATE_STA_NUM(&mstate) && mlmeext_chk_scan_backop_flags_sta(mlmeext, SS_BACKOP_EN_NL)))
14262
backop_flags |= mlmeext_scan_backop_flags_sta(mlmeext);
14263
14264
#ifdef CONFIG_AP_MODE
14265
if ((MSTATE_AP_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN))
14266
|| (MSTATE_AP_NUM(&mstate) && mlmeext_chk_scan_backop_flags_ap(mlmeext, SS_BACKOP_EN_NL)))
14267
backop_flags |= mlmeext_scan_backop_flags_ap(mlmeext);
14268
#endif
14269
14270
#ifdef CONFIG_RTW_MESH
14271
if ((MSTATE_MESH_LD_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN))
14272
|| (MSTATE_MESH_NUM(&mstate) && mlmeext_chk_scan_backop_flags_mesh(mlmeext, SS_BACKOP_EN_NL)))
14273
backop_flags |= mlmeext_scan_backop_flags_mesh(mlmeext);
14274
#endif
14275
14276
return backop_flags;
14277
}
14278
#endif
14279
14280
#define SCANNING_TIMEOUT_EX 2000
14281
u32 rtw_scan_timeout_decision(_adapter *padapter)
14282
{
14283
u32 back_op_times= 0;
14284
u8 max_chan_num;
14285
u16 scan_ms;
14286
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14287
struct ss_res *ss = &pmlmeext->sitesurvey_res;
14288
14289
if (is_supported_5g(padapter->registrypriv.wireless_mode)
14290
&& IsSupported24G(padapter->registrypriv.wireless_mode))
14291
max_chan_num = MAX_CHANNEL_NUM;/* dual band */
14292
else
14293
max_chan_num = MAX_CHANNEL_NUM_2G;/*single band*/
14294
14295
#ifdef CONFIG_SCAN_BACKOP
14296
if (rtw_scan_backop_decision(padapter))
14297
back_op_times = (max_chan_num / ss->scan_cnt_max) * ss->backop_ms;
14298
#endif
14299
14300
if (ss->duration)
14301
scan_ms = ss->duration;
14302
else
14303
#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14304
if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
14305
scan_ms = rtw_acs_get_adv_st(padapter);
14306
else
14307
#endif /*CONFIG_RTW_ACS*/
14308
scan_ms = ss->scan_ch_ms;
14309
14310
ss->scan_timeout_ms = (scan_ms * max_chan_num) + back_op_times + SCANNING_TIMEOUT_EX;
14311
#ifdef DBG_SITESURVEY
14312
RTW_INFO("%s , scan_timeout_ms = %d (ms)\n", __func__, ss->scan_timeout_ms);
14313
#endif /*DBG_SITESURVEY*/
14314
return ss->scan_timeout_ms;
14315
}
14316
14317
static int rtw_scan_ch_decision(_adapter *padapter, struct rtw_ieee80211_channel *out,
14318
u32 out_num, struct rtw_ieee80211_channel *in, u32 in_num)
14319
{
14320
int i, j;
14321
int set_idx;
14322
u8 chan;
14323
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14324
14325
/* clear first */
14326
_rtw_memset(out, 0, sizeof(struct rtw_ieee80211_channel) * out_num);
14327
14328
/* acquire channels from in */
14329
j = 0;
14330
for (i = 0; i < in_num; i++) {
14331
14332
if (0)
14333
RTW_INFO(FUNC_ADPT_FMT" "CHAN_FMT"\n", FUNC_ADPT_ARG(padapter), CHAN_ARG(&in[i]));
14334
14335
if (!in[i].hw_value || (in[i].flags & RTW_IEEE80211_CHAN_DISABLED))
14336
continue;
14337
if (rtw_mlme_band_check(padapter, in[i].hw_value) == _FALSE)
14338
continue;
14339
14340
set_idx = rtw_chset_search_ch(rfctl->channel_set, in[i].hw_value);
14341
if (set_idx >= 0) {
14342
if (j >= out_num) {
14343
RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
14344
FUNC_ADPT_ARG(padapter), out_num);
14345
break;
14346
}
14347
14348
_rtw_memcpy(&out[j], &in[i], sizeof(struct rtw_ieee80211_channel));
14349
14350
if (rfctl->channel_set[set_idx].ScanType == SCAN_PASSIVE)
14351
out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14352
14353
j++;
14354
}
14355
if (j >= out_num)
14356
break;
14357
}
14358
14359
/* if out is empty, use channel_set as default */
14360
if (j == 0) {
14361
for (i = 0; i < rfctl->max_chan_nums; i++) {
14362
chan = rfctl->channel_set[i].ChannelNum;
14363
if (rtw_mlme_band_check(padapter, chan) == _TRUE) {
14364
if (rtw_mlme_ignore_chan(padapter, chan) == _TRUE)
14365
continue;
14366
14367
if (0)
14368
RTW_INFO(FUNC_ADPT_FMT" ch:%u\n", FUNC_ADPT_ARG(padapter), chan);
14369
14370
if (j >= out_num) {
14371
RTW_PRINT(FUNC_ADPT_FMT" out_num:%u not enough\n",
14372
FUNC_ADPT_ARG(padapter), out_num);
14373
break;
14374
}
14375
14376
out[j].hw_value = chan;
14377
14378
if (rfctl->channel_set[i].ScanType == SCAN_PASSIVE)
14379
out[j].flags |= RTW_IEEE80211_CHAN_PASSIVE_SCAN;
14380
14381
j++;
14382
}
14383
}
14384
}
14385
14386
/* scan_sparse */
14387
j = rtw_scan_sparse(padapter, out, j);
14388
14389
return j;
14390
}
14391
14392
static void sitesurvey_res_reset(_adapter *adapter, struct sitesurvey_parm *parm)
14393
{
14394
struct ss_res *ss = &adapter->mlmeextpriv.sitesurvey_res;
14395
RT_CHANNEL_INFO *chset = adapter_to_chset(adapter);
14396
int i;
14397
14398
ss->bss_cnt = 0;
14399
ss->channel_idx = 0;
14400
#ifdef CONFIG_DFS
14401
ss->dfs_ch_ssid_scan = 0;
14402
#endif
14403
ss->igi_scan = 0;
14404
ss->igi_before_scan = 0;
14405
#ifdef CONFIG_SCAN_BACKOP
14406
ss->scan_cnt = 0;
14407
#endif
14408
#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
14409
ss->is_sw_antdiv_bl_scan = 0;
14410
#endif
14411
ss->ssid_num = 0;
14412
for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14413
if (parm->ssid[i].SsidLength) {
14414
_rtw_memcpy(ss->ssid[i].Ssid, parm->ssid[i].Ssid, IW_ESSID_MAX_SIZE);
14415
ss->ssid[i].SsidLength = parm->ssid[i].SsidLength;
14416
ss->ssid_num++;
14417
} else
14418
ss->ssid[i].SsidLength = 0;
14419
}
14420
14421
ss->ch_num = rtw_scan_ch_decision(adapter
14422
, ss->ch, RTW_CHANNEL_SCAN_AMOUNT
14423
, parm->ch, parm->ch_num
14424
);
14425
14426
#ifdef CONFIG_DFS
14427
for (i = 0; i < MAX_CHANNEL_NUM; i++)
14428
chset[i].hidden_bss_cnt = 0;
14429
#endif
14430
14431
ss->bw = parm->bw;
14432
ss->igi = parm->igi;
14433
ss->token = parm->token;
14434
ss->duration = parm->duration;
14435
ss->scan_mode = parm->scan_mode;
14436
ss->token = parm->token;
14437
}
14438
14439
static u8 sitesurvey_pick_ch_behavior(_adapter *padapter, u8 *ch, RT_SCAN_TYPE *type)
14440
{
14441
u8 next_state;
14442
u8 scan_ch = 0;
14443
RT_SCAN_TYPE scan_type = SCAN_PASSIVE;
14444
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14445
struct ss_res *ss = &pmlmeext->sitesurvey_res;
14446
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
14447
int ch_set_idx;
14448
#ifdef CONFIG_P2P
14449
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14450
#endif
14451
#ifdef CONFIG_SCAN_BACKOP
14452
u8 backop_flags = 0;
14453
#endif
14454
14455
/* handle scan abort request */
14456
scan_abort_hdl(padapter);
14457
14458
#ifdef CONFIG_P2P
14459
if (pwdinfo->rx_invitereq_info.scan_op_ch_only || pwdinfo->p2p_info.scan_op_ch_only) {
14460
if (pwdinfo->rx_invitereq_info.scan_op_ch_only)
14461
scan_ch = pwdinfo->rx_invitereq_info.operation_ch[ss->channel_idx];
14462
else
14463
scan_ch = pwdinfo->p2p_info.operation_ch[ss->channel_idx];
14464
scan_type = SCAN_ACTIVE;
14465
} else if (rtw_p2p_findphase_ex_is_social(pwdinfo)) {
14466
/*
14467
* Commented by Albert 2011/06/03
14468
* The driver is in the find phase, it should go through the social channel.
14469
*/
14470
scan_ch = pwdinfo->social_chan[ss->channel_idx];
14471
ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scan_ch);
14472
if (ch_set_idx >= 0)
14473
scan_type = rfctl->channel_set[ch_set_idx].ScanType;
14474
else
14475
scan_type = SCAN_ACTIVE;
14476
} else
14477
#endif /* CONFIG_P2P */
14478
{
14479
struct rtw_ieee80211_channel *ch;
14480
14481
#ifdef CONFIG_SCAN_BACKOP
14482
backop_flags = rtw_scan_backop_decision(padapter);
14483
#endif
14484
14485
#ifdef CONFIG_DFS
14486
#ifdef CONFIG_SCAN_BACKOP
14487
if (!(backop_flags && ss->scan_cnt >= ss->scan_cnt_max))
14488
#endif
14489
{
14490
#ifdef CONFIG_RTW_WIFI_HAL
14491
if (adapter_to_dvobj(padapter)->nodfs) {
14492
while ( ss->channel_idx < ss->ch_num && rtw_is_dfs_ch(ss->ch[ss->channel_idx].hw_value))
14493
ss->channel_idx++;
14494
} else
14495
#endif
14496
if (ss->channel_idx != 0 && ss->dfs_ch_ssid_scan == 0
14497
&& pmlmeext->sitesurvey_res.ssid_num
14498
&& rtw_is_dfs_ch(ss->ch[ss->channel_idx - 1].hw_value)
14499
) {
14500
ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, ss->ch[ss->channel_idx - 1].hw_value);
14501
if (ch_set_idx != -1 && rfctl->channel_set[ch_set_idx].hidden_bss_cnt
14502
&& (!IS_DFS_SLAVE_WITH_RD(rfctl)
14503
|| rtw_odm_dfs_domain_unknown(rfctl_to_dvobj(rfctl))
14504
|| !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx]))
14505
) {
14506
ss->channel_idx--;
14507
ss->dfs_ch_ssid_scan = 1;
14508
}
14509
} else
14510
ss->dfs_ch_ssid_scan = 0;
14511
}
14512
#endif /* CONFIG_DFS */
14513
14514
if (ss->channel_idx < ss->ch_num) {
14515
ch = &ss->ch[ss->channel_idx];
14516
scan_ch = ch->hw_value;
14517
14518
#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14519
if (IS_ACS_ENABLE(padapter) && rtw_is_acs_passiv_scan(padapter))
14520
scan_type = SCAN_PASSIVE;
14521
else
14522
#endif /*CONFIG_RTW_ACS*/
14523
scan_type = (ch->flags & RTW_IEEE80211_CHAN_PASSIVE_SCAN) ? SCAN_PASSIVE : SCAN_ACTIVE;
14524
}
14525
}
14526
14527
if (scan_ch != 0) {
14528
next_state = SCAN_PROCESS;
14529
14530
#ifdef CONFIG_SCAN_BACKOP
14531
if (backop_flags) {
14532
if (ss->scan_cnt < ss->scan_cnt_max)
14533
ss->scan_cnt++;
14534
else {
14535
mlmeext_assign_scan_backop_flags(pmlmeext, backop_flags);
14536
next_state = SCAN_BACKING_OP;
14537
}
14538
}
14539
#endif
14540
14541
} else if (rtw_p2p_findphase_ex_is_needed(pwdinfo)) {
14542
/* go p2p listen */
14543
next_state = SCAN_TO_P2P_LISTEN;
14544
14545
#ifdef CONFIG_ANTENNA_DIVERSITY
14546
} else if (rtw_hal_antdiv_before_linked(padapter)) {
14547
/* go sw antdiv before link */
14548
next_state = SCAN_SW_ANTDIV_BL;
14549
#endif
14550
} else {
14551
next_state = SCAN_COMPLETE;
14552
14553
#if defined(DBG_SCAN_SW_ANTDIV_BL)
14554
{
14555
/* for SCAN_SW_ANTDIV_BL state testing */
14556
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14557
int i;
14558
bool is_linked = _FALSE;
14559
14560
for (i = 0; i < dvobj->iface_nums; i++) {
14561
if (rtw_linked_check(dvobj->padapters[i]))
14562
is_linked = _TRUE;
14563
}
14564
14565
if (!is_linked) {
14566
static bool fake_sw_antdiv_bl_state = 0;
14567
14568
if (fake_sw_antdiv_bl_state == 0) {
14569
next_state = SCAN_SW_ANTDIV_BL;
14570
fake_sw_antdiv_bl_state = 1;
14571
} else
14572
fake_sw_antdiv_bl_state = 0;
14573
}
14574
}
14575
#endif /* defined(DBG_SCAN_SW_ANTDIV_BL) */
14576
}
14577
14578
#ifdef CONFIG_SCAN_BACKOP
14579
if (next_state != SCAN_PROCESS)
14580
ss->scan_cnt = 0;
14581
#endif
14582
14583
14584
#ifdef DBG_FIXED_CHAN
14585
if (pmlmeext->fixed_chan != 0xff && next_state == SCAN_PROCESS)
14586
scan_ch = pmlmeext->fixed_chan;
14587
#endif
14588
14589
if (ch)
14590
*ch = scan_ch;
14591
if (type)
14592
*type = scan_type;
14593
14594
return next_state;
14595
}
14596
14597
void site_survey(_adapter *padapter, u8 survey_channel, RT_SCAN_TYPE ScanType)
14598
{
14599
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14600
struct ss_res *ss = &pmlmeext->sitesurvey_res;
14601
u8 ssid_scan = 0;
14602
14603
#ifdef CONFIG_P2P
14604
#ifndef CONFIG_IOCTL_CFG80211
14605
struct wifidirect_info *pwdinfo = &(padapter->wdinfo);
14606
#endif
14607
#endif
14608
14609
if (survey_channel != 0) {
14610
set_channel_bwmode(padapter, survey_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
14611
14612
#ifdef CONFIG_DFS
14613
if (ScanType == SCAN_PASSIVE && ss->dfs_ch_ssid_scan)
14614
ssid_scan = 1;
14615
else
14616
#endif
14617
if (ScanType == SCAN_ACTIVE) {
14618
#ifdef CONFIG_P2P
14619
#ifdef CONFIG_IOCTL_CFG80211
14620
if (rtw_cfg80211_is_p2p_scan(padapter))
14621
#else
14622
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
14623
|| rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH))
14624
#endif
14625
{
14626
issue_probereq_p2p(padapter, NULL);
14627
issue_probereq_p2p(padapter, NULL);
14628
issue_probereq_p2p(padapter, NULL);
14629
} else
14630
#endif /* CONFIG_P2P */
14631
{
14632
if (pmlmeext->sitesurvey_res.scan_mode == SCAN_ACTIVE) {
14633
/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14634
if (padapter->registrypriv.wifi_spec)
14635
issue_probereq(padapter, NULL, NULL);
14636
else
14637
issue_probereq_ex(padapter, NULL, NULL, 0, 0, 0, 0);
14638
issue_probereq(padapter, NULL, NULL);
14639
}
14640
14641
ssid_scan = 1;
14642
}
14643
}
14644
14645
if (ssid_scan) {
14646
int i;
14647
14648
for (i = 0; i < RTW_SSID_SCAN_AMOUNT; i++) {
14649
if (pmlmeext->sitesurvey_res.ssid[i].SsidLength) {
14650
/* IOT issue, When wifi_spec is not set, send one probe req without WPS IE. */
14651
if (padapter->registrypriv.wifi_spec)
14652
issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
14653
else
14654
issue_probereq_ex(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL, 0, 0, 0, 0);
14655
issue_probereq(padapter, &(pmlmeext->sitesurvey_res.ssid[i]), NULL);
14656
}
14657
}
14658
}
14659
} else {
14660
/* channel number is 0 or this channel is not valid. */
14661
rtw_warn_on(1);
14662
}
14663
14664
return;
14665
}
14666
14667
void survey_done_set_ch_bw(_adapter *padapter)
14668
{
14669
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14670
u8 cur_channel = 0;
14671
u8 cur_bwmode;
14672
u8 cur_ch_offset;
14673
14674
#ifdef CONFIG_MCC_MODE
14675
if (!rtw_hal_mcc_change_scan_flag(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset)) {
14676
if (0)
14677
RTW_INFO(FUNC_ADPT_FMT" back to AP channel - ch:%u, bw:%u, offset:%u\n",
14678
FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14679
goto exit;
14680
}
14681
#endif
14682
14683
if (rtw_mi_get_ch_setting_union(padapter, &cur_channel, &cur_bwmode, &cur_ch_offset) != 0) {
14684
if (0)
14685
RTW_INFO(FUNC_ADPT_FMT" back to linked/linking union - ch:%u, bw:%u, offset:%u\n",
14686
FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14687
} else {
14688
#ifdef CONFIG_P2P
14689
struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
14690
_adapter *iface;
14691
int i;
14692
14693
for (i = 0; i < dvobj->iface_nums; i++) {
14694
iface = dvobj->padapters[i];
14695
if (!iface)
14696
continue;
14697
14698
#ifdef CONFIG_IOCTL_CFG80211
14699
if (iface->wdinfo.driver_interface == DRIVER_CFG80211 && !adapter_wdev_data(iface)->p2p_enabled)
14700
continue;
14701
#endif
14702
14703
if (rtw_p2p_chk_state(&iface->wdinfo, P2P_STATE_LISTEN)) {
14704
cur_channel = iface->wdinfo.listen_channel;
14705
cur_bwmode = CHANNEL_WIDTH_20;
14706
cur_ch_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
14707
if (0)
14708
RTW_INFO(FUNC_ADPT_FMT" back to "ADPT_FMT"'s listen ch - ch:%u, bw:%u, offset:%u\n",
14709
FUNC_ADPT_ARG(padapter), ADPT_ARG(iface), cur_channel, cur_bwmode, cur_ch_offset);
14710
break;
14711
}
14712
}
14713
#endif /* CONFIG_P2P */
14714
14715
if (cur_channel == 0) {
14716
cur_channel = pmlmeext->cur_channel;
14717
cur_bwmode = pmlmeext->cur_bwmode;
14718
cur_ch_offset = pmlmeext->cur_ch_offset;
14719
if (0)
14720
RTW_INFO(FUNC_ADPT_FMT" back to ch:%u, bw:%u, offset:%u\n",
14721
FUNC_ADPT_ARG(padapter), cur_channel, cur_bwmode, cur_ch_offset);
14722
}
14723
}
14724
#ifdef CONFIG_MCC_MODE
14725
exit:
14726
#endif
14727
set_channel_bwmode(padapter, cur_channel, cur_ch_offset, cur_bwmode);
14728
}
14729
14730
/**
14731
* rtw_ps_annc - check and doing ps announcement for all the adapters
14732
* @adapter: the requesting adapter
14733
* @ps: power saving or not
14734
*
14735
* Returns: 0: no ps announcement is doing. 1: ps announcement is doing
14736
*/
14737
u8 rtw_ps_annc(_adapter *adapter, bool ps)
14738
{
14739
struct dvobj_priv *dvobj = adapter_to_dvobj(adapter);
14740
_adapter *iface;
14741
int i;
14742
u8 ps_anc = 0;
14743
14744
for (i = 0; i < dvobj->iface_nums; i++) {
14745
iface = dvobj->padapters[i];
14746
if (!iface)
14747
continue;
14748
14749
if (MLME_IS_STA(iface)) {
14750
if (is_client_associated_to_ap(iface) == _TRUE) {
14751
/* TODO: TDLS peers */
14752
#ifdef CONFIG_MCC_MODE
14753
/* for two station case */
14754
if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_NEED_MCC)) {
14755
u8 ch = iface->mlmeextpriv.cur_channel;
14756
u8 offset = iface->mlmeextpriv.cur_ch_offset;
14757
u8 bw = iface->mlmeextpriv.cur_bwmode;
14758
14759
set_channel_bwmode(iface, ch, offset, bw);
14760
}
14761
#endif /* CONFIG_MCC_MODE */
14762
issue_nulldata(iface, NULL, ps, 3, 500);
14763
ps_anc = 1;
14764
}
14765
#ifdef CONFIG_RTW_MESH
14766
} else if (MLME_IS_MESH(iface)) {
14767
if (rtw_mesh_ps_annc(iface, ps))
14768
ps_anc = 1;
14769
#endif
14770
}
14771
}
14772
return ps_anc;
14773
}
14774
14775
void rtw_leave_opch(_adapter *adapter)
14776
{
14777
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
14778
14779
#ifdef CONFIG_MCC_MODE
14780
if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))
14781
return;
14782
#endif
14783
14784
_enter_critical_mutex(&rfctl->offch_mutex, NULL);
14785
14786
if (rfctl->offch_state == OFFCHS_NONE) {
14787
/* prepare to leave operating channel */
14788
rfctl->offch_state = OFFCHS_LEAVING_OP;
14789
14790
/* clear HW TX queue */
14791
rtw_hal_set_hwreg(adapter, HW_VAR_CHECK_TXBUF, 0);
14792
14793
rtw_hal_macid_sleep_all_used(adapter);
14794
14795
rtw_ps_annc(adapter, 1);
14796
14797
rfctl->offch_state = OFFCHS_LEAVE_OP;
14798
}
14799
14800
_exit_critical_mutex(&rfctl->offch_mutex, NULL);
14801
}
14802
14803
void rtw_back_opch(_adapter *adapter)
14804
{
14805
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
14806
14807
#ifdef CONFIG_MCC_MODE
14808
if (MCC_EN(adapter) && rtw_hal_check_mcc_status(adapter, MCC_STATUS_DOING_MCC))
14809
return;
14810
#endif
14811
14812
_enter_critical_mutex(&rfctl->offch_mutex, NULL);
14813
14814
if (rfctl->offch_state != OFFCHS_NONE) {
14815
rfctl->offch_state = OFFCHS_BACKING_OP;
14816
rtw_hal_macid_wakeup_all_used(adapter);
14817
rtw_ps_annc(adapter, 0);
14818
14819
rfctl->offch_state = OFFCHS_NONE;
14820
rtw_mi_os_xmit_schedule(adapter);
14821
}
14822
14823
_exit_critical_mutex(&rfctl->offch_mutex, NULL);
14824
}
14825
14826
void sitesurvey_set_igi(_adapter *adapter)
14827
{
14828
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
14829
struct ss_res *ss = &mlmeext->sitesurvey_res;
14830
u8 igi;
14831
#ifdef CONFIG_P2P
14832
struct wifidirect_info *pwdinfo = &adapter->wdinfo;
14833
#endif
14834
14835
switch (mlmeext_scan_state(mlmeext)) {
14836
case SCAN_ENTER:
14837
#ifdef CONFIG_P2P
14838
#ifdef CONFIG_IOCTL_CFG80211
14839
if (pwdinfo->driver_interface == DRIVER_CFG80211 && rtw_cfg80211_is_p2p_scan(adapter))
14840
igi = 0x30;
14841
else
14842
#endif /* CONFIG_IOCTL_CFG80211 */
14843
if (!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
14844
igi = 0x28;
14845
else
14846
#endif /* CONFIG_P2P */
14847
14848
if (ss->igi)
14849
igi = ss->igi;
14850
else
14851
#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
14852
if (IS_ACS_ENABLE(adapter) && rtw_is_acs_igi_valid(adapter))
14853
igi = rtw_acs_get_adv_igi(adapter);
14854
else
14855
#endif /*CONFIG_RTW_ACS*/
14856
igi = 0x1e;
14857
14858
/* record IGI status */
14859
ss->igi_scan = igi;
14860
rtw_hal_get_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &ss->igi_before_scan, NULL);
14861
14862
/* disable DIG and set IGI for scan */
14863
rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
14864
break;
14865
case SCAN_COMPLETE:
14866
case SCAN_TO_P2P_LISTEN:
14867
/* enable DIG and restore IGI */
14868
igi = 0xff;
14869
rtw_hal_set_odm_var(adapter, HAL_ODM_INITIAL_GAIN, &igi, _FALSE);
14870
break;
14871
#ifdef CONFIG_SCAN_BACKOP
14872
case SCAN_BACKING_OP:
14873
/* write IGI for op channel when DIG is not enabled */
14874
odm_write_dig(adapter_to_phydm(adapter), ss->igi_before_scan);
14875
break;
14876
case SCAN_LEAVE_OP:
14877
/* write IGI for scan when DIG is not enabled */
14878
odm_write_dig(adapter_to_phydm(adapter), ss->igi_scan);
14879
break;
14880
#endif /* CONFIG_SCAN_BACKOP */
14881
default:
14882
rtw_warn_on(1);
14883
break;
14884
}
14885
}
14886
void sitesurvey_set_msr(_adapter *adapter, bool enter)
14887
{
14888
u8 network_type;
14889
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
14890
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
14891
14892
if (enter) {
14893
#ifdef CONFIG_MI_WITH_MBSSID_CAM
14894
rtw_hal_get_hwreg(adapter, HW_VAR_MEDIA_STATUS, (u8 *)(&pmlmeinfo->hw_media_state));
14895
#endif
14896
/* set MSR to no link state */
14897
network_type = _HW_STATE_NOLINK_;
14898
} else {
14899
#ifdef CONFIG_MI_WITH_MBSSID_CAM
14900
network_type = pmlmeinfo->hw_media_state;
14901
#else
14902
network_type = pmlmeinfo->state & 0x3;
14903
#endif
14904
}
14905
Set_MSR(adapter, network_type);
14906
}
14907
14908
void sitesurvey_set_offch_state(_adapter *adapter, u8 scan_state)
14909
{
14910
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
14911
14912
_enter_critical_mutex(&rfctl->offch_mutex, NULL);
14913
14914
switch (scan_state) {
14915
case SCAN_DISABLE:
14916
case SCAN_BACK_OP:
14917
rfctl->offch_state = OFFCHS_NONE;
14918
break;
14919
case SCAN_START:
14920
case SCAN_LEAVING_OP:
14921
rfctl->offch_state = OFFCHS_LEAVING_OP;
14922
break;
14923
case SCAN_ENTER:
14924
case SCAN_LEAVE_OP:
14925
rfctl->offch_state = OFFCHS_LEAVE_OP;
14926
break;
14927
case SCAN_COMPLETE:
14928
case SCAN_BACKING_OP:
14929
rfctl->offch_state = OFFCHS_BACKING_OP;
14930
break;
14931
default:
14932
break;
14933
}
14934
14935
_exit_critical_mutex(&rfctl->offch_mutex, NULL);
14936
}
14937
14938
u8 sitesurvey_cmd_hdl(_adapter *padapter, u8 *pbuf)
14939
{
14940
struct sitesurvey_parm *pparm = (struct sitesurvey_parm *)pbuf;
14941
#ifdef DBG_CHECK_FW_PS_STATE
14942
struct dvobj_priv *dvobj = padapter->dvobj;
14943
struct debug_priv *pdbgpriv = &dvobj->drv_dbg;
14944
#endif
14945
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
14946
struct ss_res *ss = &pmlmeext->sitesurvey_res;
14947
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
14948
struct rtw_wdev_priv *pwdev_priv = adapter_wdev_data(padapter);
14949
#endif
14950
u8 val8;
14951
14952
#ifdef CONFIG_P2P
14953
struct wifidirect_info *pwdinfo = &padapter->wdinfo;
14954
#endif
14955
14956
#ifdef DBG_CHECK_FW_PS_STATE
14957
if (rtw_fw_ps_state(padapter) == _FAIL) {
14958
RTW_INFO("scan without leave 32k\n");
14959
pdbgpriv->dbg_scan_pwr_state_cnt++;
14960
}
14961
#endif /* DBG_CHECK_FW_PS_STATE */
14962
14963
/* increase channel idx */
14964
if (mlmeext_chk_scan_state(pmlmeext, SCAN_PROCESS))
14965
ss->channel_idx++;
14966
14967
/* update scan state to next state (assigned by previous cmd hdl) */
14968
if (mlmeext_scan_state(pmlmeext) != mlmeext_scan_next_state(pmlmeext))
14969
mlmeext_set_scan_state(pmlmeext, mlmeext_scan_next_state(pmlmeext));
14970
14971
operation_by_state:
14972
switch (mlmeext_scan_state(pmlmeext)) {
14973
14974
case SCAN_DISABLE:
14975
/*
14976
* SW parameter initialization
14977
*/
14978
14979
sitesurvey_res_reset(padapter, pparm);
14980
mlmeext_set_scan_state(pmlmeext, SCAN_START);
14981
goto operation_by_state;
14982
14983
case SCAN_START:
14984
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
14985
if ((pwdev_priv->pno_mac_addr[0] != 0xFF)
14986
&& (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _TRUE)
14987
&& (check_fwstate(&padapter->mlmepriv, _FW_LINKED) == _FALSE)) {
14988
u16 seq_num;
14989
14990
rtw_hal_pno_random_gen_mac_addr(padapter);
14991
rtw_hal_set_hw_mac_addr(padapter, pwdev_priv->pno_mac_addr);
14992
get_random_bytes(&seq_num, 2);
14993
pwdev_priv->pno_scan_seq_num = seq_num & 0xFFF;
14994
RTW_INFO("%s pno_scan_seq_num %d\n", __func__,
14995
pwdev_priv->pno_scan_seq_num);
14996
}
14997
#endif
14998
14999
/*
15000
* prepare to leave operating channel
15001
*/
15002
15003
#ifdef CONFIG_MCC_MODE
15004
rtw_hal_set_mcc_setting_scan_start(padapter);
15005
#endif /* CONFIG_MCC_MODE */
15006
15007
/* apply rx ampdu setting */
15008
if (ss->rx_ampdu_accept != RX_AMPDU_ACCEPT_INVALID
15009
|| ss->rx_ampdu_size != RX_AMPDU_SIZE_INVALID)
15010
rtw_rx_ampdu_apply(padapter);
15011
15012
/* clear HW TX queue before scan */
15013
rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
15014
15015
rtw_hal_macid_sleep_all_used(padapter);
15016
15017
/* power save state announcement */
15018
if (rtw_ps_annc(padapter, 1)) {
15019
mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
15020
mlmeext_set_scan_next_state(pmlmeext, SCAN_ENTER);
15021
set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
15022
} else {
15023
mlmeext_set_scan_state(pmlmeext, SCAN_ENTER);
15024
goto operation_by_state;
15025
}
15026
15027
break;
15028
15029
case SCAN_ENTER:
15030
/*
15031
* HW register and DM setting for enter scan
15032
*/
15033
15034
rtw_phydm_ability_backup(padapter);
15035
15036
sitesurvey_set_igi(padapter);
15037
15038
/* config dynamic functions for off channel */
15039
rtw_phydm_func_for_offchannel(padapter);
15040
/* set MSR to no link state */
15041
sitesurvey_set_msr(padapter, _TRUE);
15042
15043
val8 = 1; /* under site survey */
15044
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15045
15046
mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15047
goto operation_by_state;
15048
15049
case SCAN_PROCESS: {
15050
u8 scan_ch;
15051
RT_SCAN_TYPE scan_type;
15052
u8 next_state;
15053
u32 scan_ms;
15054
15055
#ifdef CONFIG_RTW_ACS
15056
if (IS_ACS_ENABLE(padapter))
15057
rtw_acs_get_rst(padapter);
15058
#endif
15059
15060
next_state = sitesurvey_pick_ch_behavior(padapter, &scan_ch, &scan_type);
15061
15062
if (next_state != SCAN_PROCESS) {
15063
mlmeext_set_scan_state(pmlmeext, next_state);
15064
goto operation_by_state;
15065
}
15066
15067
/* still SCAN_PROCESS state */
15068
#ifdef DBG_SITESURVEY
15069
#ifdef CONFIG_P2P
15070
RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (cnt:%u,idx:%d) at %dms, %c%c%c%c\n"
15071
, FUNC_ADPT_ARG(padapter)
15072
, mlmeext_scan_state_str(pmlmeext)
15073
, scan_ch
15074
, pwdinfo->find_phase_state_exchange_cnt, ss->channel_idx
15075
, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15076
, scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
15077
, ss->ssid[0].SsidLength ? 'S' : ' '
15078
, ss->dfs_ch_ssid_scan ? 'D' : ' '
15079
);
15080
#else
15081
RTW_INFO(FUNC_ADPT_FMT" %s ch:%u (idx:%d) at %dms, %c%c%c%c\n"
15082
, FUNC_ADPT_ARG(padapter)
15083
, mlmeext_scan_state_str(pmlmeext)
15084
, scan_ch
15085
, ss->channel_idx
15086
, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15087
, scan_type ? 'A' : 'P', ss->scan_mode ? 'A' : 'P'
15088
, ss->ssid[0].SsidLength ? 'S' : ' '
15089
, ss->dfs_ch_ssid_scan ? 'D' : ' '
15090
);
15091
#endif /* CONFIG_P2P */
15092
#endif /*DBG_SITESURVEY*/
15093
#ifdef DBG_FIXED_CHAN
15094
if (pmlmeext->fixed_chan != 0xff)
15095
RTW_INFO(FUNC_ADPT_FMT" fixed_chan:%u\n", pmlmeext->fixed_chan);
15096
#endif
15097
15098
site_survey(padapter, scan_ch, scan_type);
15099
15100
#if defined(CONFIG_ATMEL_RC_PATCH)
15101
if (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)
15102
scan_ms = 20;
15103
else
15104
scan_ms = 40;
15105
#else
15106
#if defined(CONFIG_RTW_ACS) && defined(CONFIG_RTW_ACS_DBG)
15107
if (IS_ACS_ENABLE(padapter) && rtw_is_acs_st_valid(padapter))
15108
scan_ms = rtw_acs_get_adv_st(padapter);
15109
else
15110
#endif /*CONFIG_RTW_ACS*/
15111
scan_ms = ss->scan_ch_ms;
15112
#endif
15113
15114
#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
15115
if (ss->is_sw_antdiv_bl_scan)
15116
scan_ms = scan_ms / 2;
15117
#endif
15118
15119
#ifdef CONFIG_RTW_ACS
15120
if (IS_ACS_ENABLE(padapter)) {
15121
if (pparm->token)
15122
rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_IEEE_11K_HIGH);
15123
else
15124
rtw_acs_trigger(padapter, scan_ms, scan_ch, NHM_PID_ACS);
15125
}
15126
#endif
15127
15128
#ifdef CONFIG_BACKGROUND_NOISE_MONITOR
15129
if (IS_NM_ENABLE(padapter))
15130
rtw_noise_measure(padapter, scan_ch, _FALSE, 0, scan_ms / 2);
15131
#endif
15132
set_survey_timer(pmlmeext, scan_ms);
15133
break;
15134
}
15135
15136
#ifdef CONFIG_SCAN_BACKOP
15137
case SCAN_BACKING_OP: {
15138
u8 back_ch, back_bw, back_ch_offset;
15139
u8 need_ch_setting_union = _TRUE;
15140
15141
#ifdef CONFIG_MCC_MODE
15142
need_ch_setting_union = rtw_hal_mcc_change_scan_flag(padapter,
15143
&back_ch, &back_bw, &back_ch_offset);
15144
#endif /* CONFIG_MCC_MODE */
15145
15146
if (need_ch_setting_union) {
15147
if (rtw_mi_get_ch_setting_union(padapter, &back_ch, &back_bw, &back_ch_offset) == 0)
15148
rtw_warn_on(1);
15149
}
15150
15151
#ifdef DBG_SITESURVEY
15152
RTW_INFO(FUNC_ADPT_FMT" %s ch:%u, bw:%u, offset:%u at %dms\n"
15153
, FUNC_ADPT_ARG(padapter)
15154
, mlmeext_scan_state_str(pmlmeext)
15155
, back_ch, back_bw, back_ch_offset
15156
, rtw_get_passing_time_ms(padapter->mlmepriv.scan_start_time)
15157
);
15158
#endif /*DBG_SITESURVEY*/
15159
set_channel_bwmode(padapter, back_ch, back_ch_offset, back_bw);
15160
15161
sitesurvey_set_msr(padapter, _FALSE);
15162
15163
val8 = 0; /* survey done */
15164
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15165
15166
if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)) {
15167
sitesurvey_set_igi(padapter);
15168
rtw_hal_macid_wakeup_all_used(padapter);
15169
rtw_ps_annc(padapter, 0);
15170
}
15171
15172
mlmeext_set_scan_state(pmlmeext, SCAN_BACK_OP);
15173
ss->backop_time = rtw_get_current_time();
15174
15175
if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_TX_RESUME))
15176
rtw_mi_os_xmit_schedule(padapter);
15177
15178
15179
goto operation_by_state;
15180
}
15181
15182
case SCAN_BACK_OP:
15183
if (rtw_get_passing_time_ms(ss->backop_time) >= ss->backop_ms
15184
|| pmlmeext->scan_abort
15185
) {
15186
mlmeext_set_scan_state(pmlmeext, SCAN_LEAVING_OP);
15187
goto operation_by_state;
15188
}
15189
set_survey_timer(pmlmeext, 50);
15190
break;
15191
15192
case SCAN_LEAVING_OP:
15193
/*
15194
* prepare to leave operating channel
15195
*/
15196
15197
/* clear HW TX queue before scan */
15198
rtw_hal_set_hwreg(padapter, HW_VAR_CHECK_TXBUF, 0);
15199
15200
rtw_hal_macid_sleep_all_used(padapter);
15201
if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC)
15202
&& rtw_ps_annc(padapter, 1)
15203
) {
15204
mlmeext_set_scan_state(pmlmeext, SCAN_PS_ANNC_WAIT);
15205
mlmeext_set_scan_next_state(pmlmeext, SCAN_LEAVE_OP);
15206
set_survey_timer(pmlmeext, 50); /* delay 50ms to protect nulldata(1) */
15207
} else {
15208
mlmeext_set_scan_state(pmlmeext, SCAN_LEAVE_OP);
15209
goto operation_by_state;
15210
}
15211
15212
break;
15213
15214
case SCAN_LEAVE_OP:
15215
/*
15216
* HW register and DM setting for enter scan
15217
*/
15218
15219
if (mlmeext_chk_scan_backop_flags(pmlmeext, SS_BACKOP_PS_ANNC))
15220
sitesurvey_set_igi(padapter);
15221
15222
sitesurvey_set_msr(padapter, _TRUE);
15223
15224
val8 = 1; /* under site survey */
15225
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15226
15227
mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15228
goto operation_by_state;
15229
15230
#endif /* CONFIG_SCAN_BACKOP */
15231
15232
#if defined(CONFIG_ANTENNA_DIVERSITY) || defined(DBG_SCAN_SW_ANTDIV_BL)
15233
case SCAN_SW_ANTDIV_BL:
15234
/*
15235
* 20100721
15236
* For SW antenna diversity before link, it needs to switch to another antenna and scan again.
15237
* It compares the scan result and select better one to do connection.
15238
*/
15239
ss->bss_cnt = 0;
15240
ss->channel_idx = 0;
15241
ss->is_sw_antdiv_bl_scan = 1;
15242
15243
mlmeext_set_scan_next_state(pmlmeext, SCAN_PROCESS);
15244
set_survey_timer(pmlmeext, ss->scan_ch_ms);
15245
break;
15246
#endif
15247
15248
#ifdef CONFIG_P2P
15249
case SCAN_TO_P2P_LISTEN:
15250
/*
15251
* Set the P2P State to the listen state of find phase
15252
* and set the current channel to the listen channel
15253
*/
15254
set_channel_bwmode(padapter, pwdinfo->listen_channel, HAL_PRIME_CHNL_OFFSET_DONT_CARE, CHANNEL_WIDTH_20);
15255
rtw_p2p_set_state(pwdinfo, P2P_STATE_FIND_PHASE_LISTEN);
15256
15257
/* turn on phy-dynamic functions */
15258
rtw_phydm_ability_restore(padapter);
15259
15260
sitesurvey_set_igi(padapter);
15261
15262
mlmeext_set_scan_state(pmlmeext, SCAN_P2P_LISTEN);
15263
_set_timer(&pwdinfo->find_phase_timer, (u32)((u32)pwdinfo->listen_dwell * 100));
15264
break;
15265
15266
case SCAN_P2P_LISTEN:
15267
mlmeext_set_scan_state(pmlmeext, SCAN_PROCESS);
15268
ss->channel_idx = 0;
15269
goto operation_by_state;
15270
#endif /* CONFIG_P2P */
15271
15272
case SCAN_COMPLETE:
15273
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
15274
rtw_hal_set_hw_mac_addr(padapter, adapter_mac_addr(padapter));
15275
#endif
15276
#ifdef CONFIG_P2P
15277
if (rtw_p2p_chk_state(pwdinfo, P2P_STATE_SCAN)
15278
|| rtw_p2p_chk_state(pwdinfo, P2P_STATE_FIND_PHASE_SEARCH)
15279
) {
15280
#ifdef CONFIG_CONCURRENT_MODE
15281
if (pwdinfo->driver_interface == DRIVER_WEXT) {
15282
if (rtw_mi_check_status(padapter, MI_LINKED))
15283
_set_timer(&pwdinfo->ap_p2p_switch_timer, 500);
15284
}
15285
#endif
15286
15287
rtw_p2p_set_state(pwdinfo, rtw_p2p_pre_state(pwdinfo));
15288
}
15289
rtw_p2p_findphase_ex_set(pwdinfo, P2P_FINDPHASE_EX_NONE);
15290
#endif /* CONFIG_P2P */
15291
15292
/* switch channel */
15293
survey_done_set_ch_bw(padapter);
15294
15295
sitesurvey_set_msr(padapter, _FALSE);
15296
15297
val8 = 0; /* survey done */
15298
rtw_hal_set_hwreg(padapter, HW_VAR_MLME_SITESURVEY, (u8 *)(&val8));
15299
15300
/* turn on phy-dynamic functions */
15301
rtw_phydm_ability_restore(padapter);
15302
15303
sitesurvey_set_igi(padapter);
15304
15305
#ifdef CONFIG_MCC_MODE
15306
/* start MCC fail, then tx null data */
15307
if (!rtw_hal_set_mcc_setting_scan_complete(padapter))
15308
#endif
15309
{
15310
rtw_hal_macid_wakeup_all_used(padapter);
15311
rtw_ps_annc(padapter, 0);
15312
}
15313
15314
/* apply rx ampdu setting */
15315
rtw_rx_ampdu_apply(padapter);
15316
15317
mlmeext_set_scan_state(pmlmeext, SCAN_DISABLE);
15318
15319
report_surveydone_event(padapter);
15320
#ifdef CONFIG_RTW_ACS
15321
if (IS_ACS_ENABLE(padapter))
15322
rtw_acs_select_best_chan(padapter);
15323
#endif
15324
15325
#if defined(CONFIG_BACKGROUND_NOISE_MONITOR) && defined(DBG_NOISE_MONITOR)
15326
if (IS_NM_ENABLE(padapter))
15327
rtw_noise_info_dump(RTW_DBGDUMP, padapter);
15328
#endif
15329
issue_action_BSSCoexistPacket(padapter);
15330
issue_action_BSSCoexistPacket(padapter);
15331
issue_action_BSSCoexistPacket(padapter);
15332
15333
#ifdef CONFIG_RTW_80211K
15334
if (ss->token)
15335
rm_post_event(padapter, ss->token, RM_EV_survey_done);
15336
#endif /* CONFIG_RTW_80211K */
15337
15338
break;
15339
}
15340
15341
return H2C_SUCCESS;
15342
}
15343
15344
u8 setauth_hdl(_adapter *padapter, unsigned char *pbuf)
15345
{
15346
struct setauth_parm *pparm = (struct setauth_parm *)pbuf;
15347
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15348
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15349
15350
if (pparm->mode < 4)
15351
pmlmeinfo->auth_algo = pparm->mode;
15352
15353
return H2C_SUCCESS;
15354
}
15355
15356
/*
15357
SEC CAM Entry format (32 bytes)
15358
DW0 - MAC_ADDR[15:0] | Valid[15] | MFB[14:8] | RSVD[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0]
15359
DW0 - MAC_ADDR[15:0] | Valid[15] |RSVD[14:9] | RPT_MODE[8] | SPP_MODE[7] | GK[6] | MIC_KEY[5] | SEC_TYPE[4:2] | KID[1:0] (92E/8812A/8814A)
15360
DW1 - MAC_ADDR[47:16]
15361
DW2 - KEY[31:0]
15362
DW3 - KEY[63:32]
15363
DW4 - KEY[95:64]
15364
DW5 - KEY[127:96]
15365
DW6 - RSVD
15366
DW7 - RSVD
15367
*/
15368
15369
/*Set WEP key or Group Key*/
15370
u8 setkey_hdl(_adapter *padapter, u8 *pbuf)
15371
{
15372
u16 ctrl = 0;
15373
s16 cam_id = 0;
15374
struct setkey_parm *pparm = (struct setkey_parm *)pbuf;
15375
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15376
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15377
unsigned char null_addr[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
15378
u8 *addr;
15379
bool used = _FALSE;
15380
15381
/* main tx key for wep. */
15382
if (pparm->set_tx)
15383
pmlmeinfo->key_index = pparm->keyid;
15384
15385
#ifdef CONFIG_CONCURRENT_MODE
15386
if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE))
15387
cam_id = rtw_iface_bcmc_id_get(padapter);
15388
else
15389
#endif
15390
cam_id = rtw_camid_alloc(padapter, NULL, pparm->keyid, 1, &used);
15391
15392
if (cam_id < 0)
15393
goto enable_mc;
15394
15395
#ifndef CONFIG_CONCURRENT_MODE
15396
if (cam_id >= 0 && cam_id <= 3) {
15397
/* default key camid */
15398
addr = null_addr;
15399
} else
15400
#endif
15401
{
15402
/* not default key camid */
15403
if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
15404
/* group TX, force sec cam entry_id */
15405
addr = adapter_mac_addr(padapter);
15406
} else {
15407
/* group RX, searched by A2 (TA) */
15408
addr = get_bssid(&padapter->mlmepriv);
15409
}
15410
}
15411
15412
#ifdef CONFIG_LPS_PG
15413
if (adapter_to_pwrctl(padapter)->lps_level == LPS_PG)
15414
LPS_Leave(padapter, "SET_KEY");
15415
#endif
15416
15417
/* cam entry searched is pairwise key */
15418
if (used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _FALSE) {
15419
s16 camid_clr;
15420
15421
RTW_PRINT(FUNC_ADPT_FMT" group key with "MAC_FMT" id:%u the same key id as pairwise key\n"
15422
, FUNC_ADPT_ARG(padapter), MAC_ARG(addr), pparm->keyid);
15423
15424
/* HW has problem to distinguish this group key with existing pairwise key, stop HW enc and dec for BMC */
15425
rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
15426
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
15427
15428
/* clear group key */
15429
while ((camid_clr = rtw_camid_search(padapter, addr, -1, 1)) >= 0) {
15430
RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(addr), camid_clr);
15431
clear_cam_entry(padapter, camid_clr);
15432
rtw_camid_free(padapter, camid_clr);
15433
}
15434
15435
goto enable_mc;
15436
}
15437
15438
ctrl = BIT(15) | BIT(6) | ((pparm->algorithm) << 2) | pparm->keyid;
15439
15440
RTW_PRINT("set group key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
15441
, cam_id, MAC_ARG(addr), pparm->keyid, security_type_str(pparm->algorithm));
15442
15443
write_cam(padapter, cam_id, ctrl, addr, pparm->key);
15444
15445
/* if ((cam_id > 3) && (((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)))*/
15446
#ifdef CONFIG_CONCURRENT_MODE
15447
if (((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE) || ((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)) {
15448
if (is_wep_enc(pparm->algorithm)) {
15449
padapter->securitypriv.dot11Def_camid[pparm->keyid] = cam_id;
15450
padapter->securitypriv.dot118021x_bmc_cam_id =
15451
padapter->securitypriv.dot11Def_camid[padapter->securitypriv.dot11PrivacyKeyIndex];
15452
RTW_PRINT("wep group key - force camid:%d\n", padapter->securitypriv.dot118021x_bmc_cam_id);
15453
} else {
15454
/*u8 org_cam_id = padapter->securitypriv.dot118021x_bmc_cam_id;*/
15455
15456
/*force GK's cam id*/
15457
padapter->securitypriv.dot118021x_bmc_cam_id = cam_id;
15458
15459
/* for GTK rekey
15460
if ((org_cam_id != INVALID_SEC_MAC_CAM_ID) &&
15461
(org_cam_id != cam_id)) {
15462
RTW_PRINT("clear group key for addr:"MAC_FMT", org_camid:%d new_camid:%d\n", MAC_ARG(addr), org_cam_id, cam_id);
15463
clear_cam_entry(padapter, org_cam_id);
15464
rtw_camid_free(padapter, org_cam_id);
15465
}*/
15466
}
15467
}
15468
#endif
15469
15470
15471
#ifndef CONFIG_CONCURRENT_MODE
15472
if (cam_id >= 0 && cam_id <= 3)
15473
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_DK_CFG, (u8 *)_TRUE);
15474
#endif
15475
15476
/* 8814au should set both broadcast and unicast CAM entry for WEP key in STA mode */
15477
if (is_wep_enc(pparm->algorithm) && check_mlmeinfo_state(pmlmeext, WIFI_FW_STATION_STATE) &&
15478
_rtw_camctl_chk_cap(padapter, SEC_CAP_CHK_BMC)) {
15479
struct set_stakey_parm sta_pparm;
15480
15481
_rtw_memset(&sta_pparm, 0, sizeof(struct set_stakey_parm));
15482
sta_pparm.algorithm = pparm->algorithm;
15483
sta_pparm.keyid = pparm->keyid;
15484
_rtw_memcpy(sta_pparm.key, pparm->key, 16);
15485
_rtw_memcpy(sta_pparm.addr, get_bssid(&padapter->mlmepriv), ETH_ALEN);
15486
set_stakey_hdl(padapter, (u8 *)&sta_pparm);
15487
}
15488
15489
enable_mc:
15490
/* allow multicast packets to driver */
15491
rtw_hal_set_hwreg(padapter, HW_VAR_ON_RCR_AM, null_addr);
15492
15493
return H2C_SUCCESS;
15494
}
15495
15496
void rtw_ap_wep_pk_setting(_adapter *adapter, struct sta_info *psta)
15497
{
15498
struct security_priv *psecuritypriv = &(adapter->securitypriv);
15499
struct set_stakey_parm sta_pparm;
15500
sint keyid;
15501
15502
if (!is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm))
15503
return;
15504
15505
for (keyid = 0; keyid < 4; keyid++) {
15506
if ((psecuritypriv->key_mask & BIT(keyid)) && (keyid == psecuritypriv->dot11PrivacyKeyIndex)) {
15507
sta_pparm.algorithm = psecuritypriv->dot11PrivacyAlgrthm;
15508
sta_pparm.keyid = keyid;
15509
sta_pparm.gk = 0;
15510
_rtw_memcpy(sta_pparm.key, &(psecuritypriv->dot11DefKey[keyid].skey[0]), 16);
15511
_rtw_memcpy(sta_pparm.addr, psta->cmn.mac_addr, ETH_ALEN);
15512
15513
RTW_PRINT(FUNC_ADPT_FMT"set WEP - PK with "MAC_FMT" keyid:%u\n"
15514
, FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr), keyid);
15515
15516
set_stakey_hdl(adapter, (u8 *)&sta_pparm);
15517
}
15518
}
15519
}
15520
15521
u8 set_stakey_hdl(_adapter *padapter, u8 *pbuf)
15522
{
15523
u16 ctrl = 0;
15524
s16 cam_id = 0;
15525
bool used;
15526
u8 ret = H2C_SUCCESS;
15527
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15528
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15529
struct set_stakey_parm *pparm = (struct set_stakey_parm *)pbuf;
15530
struct sta_priv *pstapriv = &padapter->stapriv;
15531
struct sta_info *psta;
15532
15533
if (pparm->algorithm == _NO_PRIVACY_)
15534
goto write_to_cam;
15535
15536
psta = rtw_get_stainfo(pstapriv, pparm->addr);
15537
if (!psta) {
15538
RTW_PRINT("%s sta:"MAC_FMT" not found\n", __func__, MAC_ARG(pparm->addr));
15539
ret = H2C_REJECTED;
15540
goto exit;
15541
}
15542
15543
pmlmeinfo->enc_algo = pparm->algorithm;
15544
15545
cam_id = rtw_camid_alloc(padapter, psta, pparm->keyid, pparm->gk, &used);
15546
if (cam_id < 0)
15547
goto exit;
15548
15549
#ifdef CONFIG_LPS_PG
15550
if (adapter_to_pwrctl(padapter)->lps_level == LPS_PG)
15551
LPS_Leave(padapter, "SET_KEY");
15552
#endif
15553
15554
/* cam entry searched is group key when setting pariwise key */
15555
if (!pparm->gk && used == _TRUE && rtw_camid_is_gk(padapter, cam_id) == _TRUE) {
15556
s16 camid_clr;
15557
15558
RTW_PRINT(FUNC_ADPT_FMT" pairwise key with "MAC_FMT" id:%u the same key id as group key\n"
15559
, FUNC_ADPT_ARG(padapter), MAC_ARG(pparm->addr), pparm->keyid);
15560
15561
/* HW has problem to distinguish this pairwise key with existing group key, stop HW enc and dec for BMC */
15562
rtw_camctl_set_flags(padapter, SEC_STATUS_STA_PK_GK_CONFLICT_DIS_BMC_SEARCH);
15563
rtw_hal_set_hwreg(padapter, HW_VAR_SEC_CFG, NULL);
15564
15565
/* clear group key */
15566
while ((camid_clr = rtw_camid_search(padapter, pparm->addr, -1, 1)) >= 0) {
15567
RTW_PRINT("clear group key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), camid_clr);
15568
clear_cam_entry(padapter, camid_clr);
15569
rtw_camid_free(padapter, camid_clr);
15570
}
15571
}
15572
15573
write_to_cam:
15574
if (pparm->algorithm == _NO_PRIVACY_) {
15575
while ((cam_id = rtw_camid_search(padapter, pparm->addr, -1, -1)) >= 0) {
15576
RTW_PRINT("clear key for addr:"MAC_FMT", camid:%d\n", MAC_ARG(pparm->addr), cam_id);
15577
clear_cam_entry(padapter, cam_id);
15578
rtw_camid_free(padapter, cam_id);
15579
}
15580
} else {
15581
RTW_PRINT("set %s key camid:%d, addr:"MAC_FMT", kid:%d, type:%s\n"
15582
, pparm->gk ? "group" : "pairwise"
15583
, cam_id, MAC_ARG(pparm->addr), pparm->keyid, security_type_str(pparm->algorithm));
15584
ctrl = BIT(15) | ((pparm->algorithm) << 2) | pparm->keyid;
15585
if (pparm->gk)
15586
ctrl |= BIT(6);
15587
write_cam(padapter, cam_id, ctrl, pparm->addr, pparm->key);
15588
}
15589
ret = H2C_SUCCESS_RSP;
15590
15591
exit:
15592
return ret;
15593
}
15594
15595
u8 add_ba_hdl(_adapter *padapter, unsigned char *pbuf)
15596
{
15597
struct addBaReq_parm *pparm = (struct addBaReq_parm *)pbuf;
15598
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15599
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15600
15601
struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, pparm->addr);
15602
15603
if (!psta)
15604
return H2C_SUCCESS;
15605
15606
#ifdef CONFIG_80211N_HT
15607
if (((pmlmeinfo->state & WIFI_FW_ASSOC_SUCCESS) && (pmlmeinfo->HT_enable)) ||
15608
((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE)) {
15609
/* pmlmeinfo->ADDBA_retry_count = 0; */
15610
/* pmlmeinfo->candidate_tid_bitmap |= (0x1 << pparm->tid); */
15611
/* psta->htpriv.candidate_tid_bitmap |= BIT(pparm->tid); */
15612
issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
15613
_set_timer(&psta->addba_retry_timer, ADDBA_TO);
15614
}
15615
#ifdef CONFIG_TDLS
15616
else if ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
15617
(psta->htpriv.ht_option == _TRUE) &&
15618
(psta->htpriv.ampdu_enable == _TRUE)) {
15619
issue_addba_req(padapter, pparm->addr, (u8)pparm->tid);
15620
_set_timer(&psta->addba_retry_timer, ADDBA_TO);
15621
}
15622
#endif /* CONFIG */
15623
else
15624
psta->htpriv.candidate_tid_bitmap &= ~BIT(pparm->tid);
15625
#endif /* CONFIG_80211N_HT */
15626
return H2C_SUCCESS;
15627
}
15628
15629
15630
u8 add_ba_rsp_hdl(_adapter *padapter, unsigned char *pbuf)
15631
{
15632
struct addBaRsp_parm *pparm = (struct addBaRsp_parm *)pbuf;
15633
struct recv_reorder_ctrl *preorder_ctrl;
15634
struct sta_priv *pstapriv = &padapter->stapriv;
15635
struct sta_info *psta;
15636
u8 ret = _TRUE;
15637
15638
psta = rtw_get_stainfo(pstapriv, pparm->addr);
15639
if (!psta)
15640
goto exit;
15641
15642
preorder_ctrl = &psta->recvreorder_ctrl[pparm->tid];
15643
ret = issue_addba_rsp_wait_ack(padapter, pparm->addr, pparm->tid, pparm->status, pparm->size, 3, 50);
15644
15645
#ifdef CONFIG_UPDATE_INDICATE_SEQ_WHILE_PROCESS_ADDBA_REQ
15646
/* status = 0 means accept this addba req, so update indicate seq = start_seq under this compile flag */
15647
if (pparm->status == 0) {
15648
preorder_ctrl->indicate_seq = pparm->start_seq;
15649
#ifdef DBG_RX_SEQ
15650
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_UPDATE indicate_seq:%d, start_seq:%d\n"
15651
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pparm->start_seq);
15652
#endif
15653
}
15654
#else
15655
rtw_set_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack);
15656
#ifdef DBG_RX_SEQ
15657
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_CLEAR indicate_seq:%d, start_seq:%d preorder_ctrl->rec_abba_rsp_ack =%lu \n"
15658
, FUNC_ADPT_ARG(padapter)
15659
, preorder_ctrl->tid
15660
, preorder_ctrl->indicate_seq
15661
, pparm->start_seq
15662
,preorder_ctrl->rec_abba_rsp_ack
15663
);
15664
#endif
15665
#endif
15666
15667
/*
15668
* status = 0 means accept this addba req
15669
* status = 37 means reject this addba req
15670
*/
15671
if (pparm->status == 0) {
15672
preorder_ctrl->enable = _TRUE;
15673
preorder_ctrl->ampdu_size = pparm->size;
15674
} else if (pparm->status == 37)
15675
preorder_ctrl->enable = _FALSE;
15676
15677
exit:
15678
return H2C_SUCCESS;
15679
}
15680
15681
u8 chk_bmc_sleepq_cmd(_adapter *padapter)
15682
{
15683
struct cmd_obj *ph2c;
15684
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
15685
u8 res = _SUCCESS;
15686
15687
15688
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
15689
if (ph2c == NULL) {
15690
res = _FAIL;
15691
goto exit;
15692
}
15693
15694
init_h2fwcmd_w_parm_no_parm_rsp(ph2c, GEN_CMD_CODE(_ChkBMCSleepq));
15695
15696
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
15697
15698
exit:
15699
15700
15701
return res;
15702
}
15703
15704
u8 set_tx_beacon_cmd(_adapter *padapter, u8 flags)
15705
{
15706
struct cmd_obj *ph2c;
15707
struct Tx_Beacon_param *ptxBeacon_parm;
15708
struct cmd_priv *pcmdpriv = &(padapter->cmdpriv);
15709
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
15710
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
15711
struct submit_ctx sctx;
15712
u8 res = _SUCCESS;
15713
int len_diff = 0;
15714
15715
/*prepare cmd parameter*/
15716
ptxBeacon_parm = (struct Tx_Beacon_param *)rtw_zmalloc(sizeof(struct Tx_Beacon_param));
15717
if (ptxBeacon_parm == NULL) {
15718
res = _FAIL;
15719
goto exit;
15720
}
15721
15722
_rtw_memcpy(&(ptxBeacon_parm->network), &(pmlmeinfo->network), sizeof(WLAN_BSSID_EX));
15723
15724
len_diff = update_hidden_ssid(
15725
ptxBeacon_parm->network.IEs + _BEACON_IE_OFFSET_
15726
, ptxBeacon_parm->network.IELength - _BEACON_IE_OFFSET_
15727
, pmlmeinfo->hidden_ssid_mode
15728
);
15729
ptxBeacon_parm->network.IELength += len_diff;
15730
15731
15732
/* need enqueue, prepare cmd_obj and enqueue */
15733
ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
15734
if (ph2c == NULL) {
15735
res = _FAIL;
15736
rtw_mfree((u8 *)ptxBeacon_parm, sizeof(*ptxBeacon_parm));
15737
goto exit;
15738
}
15739
15740
init_h2fwcmd_w_parm_no_rsp(ph2c, ptxBeacon_parm, GEN_CMD_CODE(_TX_Beacon));
15741
15742
if (flags & RTW_CMDF_WAIT_ACK) {
15743
ph2c->sctx = &sctx;
15744
rtw_sctx_init(&sctx, 10 * 1000);
15745
}
15746
15747
res = rtw_enqueue_cmd(pcmdpriv, ph2c);
15748
15749
if (res == _SUCCESS && (flags & RTW_CMDF_WAIT_ACK)) {
15750
rtw_sctx_wait(&sctx, __func__);
15751
_enter_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
15752
if (sctx.status == RTW_SCTX_SUBMITTED)
15753
ph2c->sctx = NULL;
15754
_exit_critical_mutex(&pcmdpriv->sctx_mutex, NULL);
15755
}
15756
15757
15758
exit:
15759
15760
15761
return res;
15762
}
15763
15764
15765
u8 mlme_evt_hdl(_adapter *padapter, unsigned char *pbuf)
15766
{
15767
u8 evt_code, evt_seq;
15768
u16 evt_sz;
15769
uint *peventbuf;
15770
void (*event_callback)(_adapter *dev, u8 *pbuf);
15771
struct evt_priv *pevt_priv = &(padapter->evtpriv);
15772
15773
if (pbuf == NULL)
15774
goto _abort_event_;
15775
15776
peventbuf = (uint *)pbuf;
15777
evt_sz = (u16)(*peventbuf & 0xffff);
15778
evt_seq = (u8)((*peventbuf >> 24) & 0x7f);
15779
evt_code = (u8)((*peventbuf >> 16) & 0xff);
15780
15781
15782
#ifdef CHECK_EVENT_SEQ
15783
/* checking event sequence... */
15784
if (evt_seq != (ATOMIC_READ(&pevt_priv->event_seq) & 0x7f)) {
15785
15786
pevt_priv->event_seq = (evt_seq + 1) & 0x7f;
15787
15788
goto _abort_event_;
15789
}
15790
#endif
15791
15792
/* checking if event code is valid */
15793
if (evt_code >= MAX_C2HEVT) {
15794
goto _abort_event_;
15795
}
15796
15797
/* checking if event size match the event parm size */
15798
if ((wlanevents[evt_code].parmsize != 0) &&
15799
(wlanevents[evt_code].parmsize != evt_sz)) {
15800
15801
goto _abort_event_;
15802
15803
}
15804
15805
ATOMIC_INC(&pevt_priv->event_seq);
15806
15807
peventbuf += 2;
15808
15809
if (peventbuf) {
15810
event_callback = wlanevents[evt_code].event_callback;
15811
event_callback(padapter, (u8 *)peventbuf);
15812
15813
pevt_priv->evt_done_cnt++;
15814
}
15815
15816
15817
_abort_event_:
15818
15819
15820
return H2C_SUCCESS;
15821
15822
}
15823
15824
u8 h2c_msg_hdl(_adapter *padapter, unsigned char *pbuf)
15825
{
15826
if (!pbuf)
15827
return H2C_PARAMETERS_ERROR;
15828
15829
return H2C_SUCCESS;
15830
}
15831
15832
u8 chk_bmc_sleepq_hdl(_adapter *padapter, unsigned char *pbuf)
15833
{
15834
#ifdef CONFIG_AP_MODE
15835
_irqL irqL;
15836
struct sta_info *psta_bmc;
15837
_list *xmitframe_plist, *xmitframe_phead;
15838
struct xmit_frame *pxmitframe = NULL;
15839
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
15840
struct sta_priv *pstapriv = &padapter->stapriv;
15841
15842
/* for BC/MC Frames */
15843
psta_bmc = rtw_get_bcmc_stainfo(padapter);
15844
if (!psta_bmc)
15845
return H2C_SUCCESS;
15846
15847
if ((rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, 0)) && (psta_bmc->sleepq_len > 0)) {
15848
#ifndef CONFIG_PCI_HCI
15849
rtw_msleep_os(10);/* 10ms, ATIM(HIQ) Windows */
15850
#endif
15851
/* _enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
15852
_enter_critical_bh(&pxmitpriv->lock, &irqL);
15853
15854
xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
15855
xmitframe_plist = get_next(xmitframe_phead);
15856
15857
while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
15858
pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
15859
15860
xmitframe_plist = get_next(xmitframe_plist);
15861
15862
rtw_list_delete(&pxmitframe->list);
15863
15864
psta_bmc->sleepq_len--;
15865
if (psta_bmc->sleepq_len > 0)
15866
pxmitframe->attrib.mdata = 1;
15867
else
15868
pxmitframe->attrib.mdata = 0;
15869
15870
pxmitframe->attrib.triggered = 1;
15871
15872
if (xmitframe_hiq_filter(pxmitframe) == _TRUE)
15873
pxmitframe->attrib.qsel = QSLT_HIGH;/* HIQ */
15874
15875
#if 0
15876
_exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15877
if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
15878
rtw_os_xmit_complete(padapter, pxmitframe);
15879
_enter_critical_bh(&psta_bmc->sleep_q.lock, &irqL);
15880
#endif
15881
rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
15882
}
15883
15884
/* _exit_critical_bh(&psta_bmc->sleep_q.lock, &irqL); */
15885
_exit_critical_bh(&pxmitpriv->lock, &irqL);
15886
15887
if (rtw_get_intf_type(padapter) != RTW_PCIE) {
15888
/* check hi queue and bmc_sleepq */
15889
rtw_chk_hi_queue_cmd(padapter);
15890
}
15891
}
15892
#endif
15893
15894
return H2C_SUCCESS;
15895
}
15896
15897
u8 tx_beacon_hdl(_adapter *padapter, unsigned char *pbuf)
15898
{
15899
/*RTW_INFO(FUNC_ADPT_FMT, FUNC_ADPT_ARG(padapter));*/
15900
#ifdef CONFIG_SWTIMER_BASED_TXBCN
15901
15902
tx_beacon_handlder(padapter->dvobj);
15903
15904
#else
15905
15906
if (send_beacon(padapter) == _FAIL) {
15907
RTW_INFO("issue_beacon, fail!\n");
15908
return H2C_PARAMETERS_ERROR;
15909
}
15910
15911
/* tx bc/mc frames after update TIM */
15912
chk_bmc_sleepq_hdl(padapter, NULL);
15913
#endif
15914
15915
return H2C_SUCCESS;
15916
}
15917
15918
/*
15919
* according to channel
15920
* add/remove WLAN_BSSID_EX.IEs's ERP ie
15921
* set WLAN_BSSID_EX.SupportedRates
15922
* update WLAN_BSSID_EX.IEs's Supported Rate and Extended Supported Rate ie
15923
*/
15924
void change_band_update_ie(_adapter *padapter, WLAN_BSSID_EX *pnetwork, u8 ch)
15925
{
15926
u8 network_type, rate_len, total_rate_len, remainder_rate_len;
15927
struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
15928
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
15929
u8 erpinfo = 0x4;
15930
15931
if (ch >= 36) {
15932
network_type = WIRELESS_11A;
15933
total_rate_len = IEEE80211_NUM_OFDM_RATESLEN;
15934
rtw_remove_bcn_ie(padapter, pnetwork, _ERPINFO_IE_);
15935
#ifdef CONFIG_80211AC_VHT
15936
/* if channel in 5G band, then add vht ie . */
15937
if ((pmlmepriv->htpriv.ht_option == _TRUE)
15938
&& REGSTY_IS_11AC_ENABLE(&padapter->registrypriv)
15939
&& is_supported_vht(padapter->registrypriv.wireless_mode)
15940
&& (!rfctl->country_ent || COUNTRY_CHPLAN_EN_11AC(rfctl->country_ent))
15941
) {
15942
if (REGSTY_IS_11AC_AUTO(&padapter->registrypriv)
15943
|| pmlmepriv->ori_vht_en)
15944
rtw_vht_ies_attach(padapter, pnetwork);
15945
}
15946
#endif
15947
} else {
15948
network_type = 0;
15949
total_rate_len = 0;
15950
if (padapter->registrypriv.wireless_mode & WIRELESS_11B) {
15951
network_type |= WIRELESS_11B;
15952
total_rate_len += IEEE80211_CCK_RATE_LEN;
15953
}
15954
if (padapter->registrypriv.wireless_mode & WIRELESS_11G) {
15955
network_type |= WIRELESS_11G;
15956
total_rate_len += IEEE80211_NUM_OFDM_RATESLEN;
15957
}
15958
rtw_add_bcn_ie(padapter, pnetwork, _ERPINFO_IE_, &erpinfo, 1);
15959
#ifdef CONFIG_80211AC_VHT
15960
rtw_vht_ies_detach(padapter, pnetwork);
15961
#endif
15962
}
15963
15964
rtw_set_supported_rate(pnetwork->SupportedRates, network_type);
15965
15966
UpdateBrateTbl(padapter, pnetwork->SupportedRates);
15967
15968
if (total_rate_len > 8) {
15969
rate_len = 8;
15970
remainder_rate_len = total_rate_len - 8;
15971
} else {
15972
rate_len = total_rate_len;
15973
remainder_rate_len = 0;
15974
}
15975
15976
rtw_add_bcn_ie(padapter, pnetwork, _SUPPORTEDRATES_IE_, pnetwork->SupportedRates, rate_len);
15977
15978
if (remainder_rate_len)
15979
rtw_add_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_, (pnetwork->SupportedRates + 8), remainder_rate_len);
15980
else
15981
rtw_remove_bcn_ie(padapter, pnetwork, _EXT_SUPPORTEDRATES_IE_);
15982
15983
pnetwork->Length = get_WLAN_BSSID_EX_sz(pnetwork);
15984
}
15985
15986
void rtw_join_done_chk_ch(_adapter *adapter, int join_res)
15987
{
15988
#define DUMP_ADAPTERS_STATUS 0
15989
15990
struct dvobj_priv *dvobj;
15991
_adapter *iface;
15992
struct mlme_priv *mlme;
15993
struct mlme_ext_priv *mlmeext;
15994
u8 u_ch, u_offset, u_bw;
15995
int i;
15996
15997
dvobj = adapter_to_dvobj(adapter);
15998
15999
if (DUMP_ADAPTERS_STATUS) {
16000
RTW_INFO(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
16001
dump_adapters_status(RTW_DBGDUMP , dvobj);
16002
}
16003
16004
if (join_res >= 0) {
16005
16006
#ifdef CONFIG_MCC_MODE
16007
/* MCC setting success, don't go to ch union process */
16008
if (rtw_hal_set_mcc_setting_join_done_chk_ch(adapter))
16009
return;
16010
#endif /* CONFIG_MCC_MODE */
16011
16012
if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
16013
dump_adapters_status(RTW_DBGDUMP , dvobj);
16014
rtw_warn_on(1);
16015
}
16016
16017
for (i = 0; i < dvobj->iface_nums; i++) {
16018
iface = dvobj->padapters[i];
16019
mlme = &iface->mlmepriv;
16020
mlmeext = &iface->mlmeextpriv;
16021
16022
if (!iface || iface == adapter)
16023
continue;
16024
16025
if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16026
&& check_fwstate(mlme, WIFI_ASOC_STATE)
16027
) {
16028
u8 ori_ch, ori_bw, ori_offset;
16029
bool is_grouped = rtw_is_chbw_grouped(u_ch, u_bw, u_offset
16030
, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16031
16032
if (is_grouped == _FALSE) {
16033
/* handle AP which need to switch ch setting */
16034
16035
ori_ch = mlmeext->cur_channel;
16036
ori_bw = mlmeext->cur_bwmode;
16037
ori_offset = mlmeext->cur_ch_offset;
16038
16039
/* restore original bw, adjust bw by registry setting on target ch */
16040
mlmeext->cur_bwmode = mlme->ori_bw;
16041
mlmeext->cur_channel = u_ch;
16042
rtw_adjust_chbw(iface, mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
16043
#ifdef CONFIG_RTW_MESH
16044
if (MLME_IS_MESH(iface))
16045
rtw_mesh_adjust_chbw(mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset);
16046
#endif
16047
16048
rtw_chset_sync_chbw(adapter_to_chset(adapter)
16049
, &mlmeext->cur_channel, &mlmeext->cur_bwmode, &mlmeext->cur_ch_offset
16050
, &u_ch, &u_bw, &u_offset);
16051
16052
RTW_INFO(FUNC_ADPT_FMT" %u,%u,%u => %u,%u,%u\n", FUNC_ADPT_ARG(iface)
16053
, ori_ch, ori_bw, ori_offset
16054
, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16055
16056
rtw_ap_update_bss_chbw(iface, &(mlmeext->mlmext_info.network)
16057
, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset);
16058
16059
_rtw_memcpy(&(mlme->cur_network.network), &(mlmeext->mlmext_info.network), sizeof(WLAN_BSSID_EX));
16060
16061
rtw_start_bss_hdl_after_chbw_decided(iface);
16062
16063
{
16064
#if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
16065
u8 ht_option = 0;
16066
16067
#ifdef CONFIG_80211N_HT
16068
ht_option = mlme->htpriv.ht_option;
16069
#endif
16070
16071
rtw_cfg80211_ch_switch_notify(iface
16072
, mlmeext->cur_channel, mlmeext->cur_bwmode, mlmeext->cur_ch_offset
16073
, ht_option
16074
, 0);
16075
#endif
16076
}
16077
}
16078
16079
clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16080
update_beacon(iface, 0xFF, NULL, _TRUE, 0);
16081
}
16082
}
16083
16084
#ifdef CONFIG_DFS_MASTER
16085
rtw_dfs_rd_en_decision(adapter, MLME_STA_CONNECTED, 0);
16086
#endif
16087
} else {
16088
for (i = 0; i < dvobj->iface_nums; i++) {
16089
iface = dvobj->padapters[i];
16090
mlme = &iface->mlmepriv;
16091
mlmeext = &iface->mlmeextpriv;
16092
16093
if (!iface || iface == adapter)
16094
continue;
16095
16096
if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16097
&& check_fwstate(mlme, WIFI_ASOC_STATE)
16098
) {
16099
clr_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16100
update_beacon(iface, 0xFF, NULL, _TRUE, 0);
16101
}
16102
}
16103
#ifdef CONFIG_DFS_MASTER
16104
rtw_dfs_rd_en_decision(adapter, MLME_STA_DISCONNECTED, 0);
16105
#endif
16106
}
16107
16108
if (rtw_mi_get_ch_setting_union(adapter, &u_ch, &u_bw, &u_offset)) {
16109
RTW_INFO(FUNC_ADPT_FMT" union:%u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16110
set_channel_bwmode(adapter, u_ch, u_offset, u_bw);
16111
rtw_mi_update_union_chan_inf(adapter, u_ch, u_offset, u_bw);
16112
}
16113
16114
if (DUMP_ADAPTERS_STATUS) {
16115
RTW_INFO(FUNC_ADPT_FMT" exit\n", FUNC_ADPT_ARG(adapter));
16116
dump_adapters_status(RTW_DBGDUMP , dvobj);
16117
}
16118
}
16119
16120
int rtw_chk_start_clnt_join(_adapter *adapter, u8 *ch, u8 *bw, u8 *offset)
16121
{
16122
#ifdef CONFIG_CONCURRENT_MODE
16123
bool chbw_allow = _TRUE;
16124
#endif
16125
bool connect_allow = _TRUE;
16126
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
16127
u8 cur_ch, cur_bw, cur_ch_offset;
16128
u8 u_ch, u_offset, u_bw;
16129
16130
u_ch = cur_ch = pmlmeext->cur_channel;
16131
u_bw = cur_bw = pmlmeext->cur_bwmode;
16132
u_offset = cur_ch_offset = pmlmeext->cur_ch_offset;
16133
16134
if (!ch || !bw || !offset) {
16135
connect_allow = _FALSE;
16136
rtw_warn_on(1);
16137
goto exit;
16138
}
16139
16140
if (cur_ch == 0) {
16141
connect_allow = _FALSE;
16142
RTW_ERR(FUNC_ADPT_FMT" cur_ch:%u\n"
16143
, FUNC_ADPT_ARG(adapter), cur_ch);
16144
rtw_warn_on(1);
16145
goto exit;
16146
}
16147
RTW_INFO(FUNC_ADPT_FMT" req: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16148
16149
#ifdef CONFIG_CONCURRENT_MODE
16150
{
16151
struct dvobj_priv *dvobj;
16152
_adapter *iface;
16153
struct mlme_priv *mlme;
16154
struct mlme_ext_priv *mlmeext;
16155
struct mi_state mstate;
16156
int i;
16157
16158
dvobj = adapter_to_dvobj(adapter);
16159
16160
rtw_mi_status_no_self(adapter, &mstate);
16161
RTW_INFO(FUNC_ADPT_FMT" others ld_sta_num:%u, ap_num:%u, mesh_num:%u\n"
16162
, FUNC_ADPT_ARG(adapter), MSTATE_STA_LD_NUM(&mstate)
16163
, MSTATE_AP_NUM(&mstate), MSTATE_MESH_NUM(&mstate));
16164
16165
if (!MSTATE_STA_LD_NUM(&mstate) && !MSTATE_AP_NUM(&mstate) && !MSTATE_MESH_NUM(&mstate)) {
16166
/* consider linking STA? */
16167
goto connect_allow_hdl;
16168
}
16169
16170
if (rtw_mi_get_ch_setting_union_no_self(adapter, &u_ch, &u_bw, &u_offset) <= 0) {
16171
dump_adapters_status(RTW_DBGDUMP , dvobj);
16172
rtw_warn_on(1);
16173
}
16174
RTW_INFO(FUNC_ADPT_FMT" others union:%u,%u,%u\n"
16175
, FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16176
16177
/* chbw_allow? */
16178
chbw_allow = rtw_is_chbw_grouped(pmlmeext->cur_channel, pmlmeext->cur_bwmode, pmlmeext->cur_ch_offset
16179
, u_ch, u_bw, u_offset);
16180
16181
RTW_INFO(FUNC_ADPT_FMT" chbw_allow:%d\n"
16182
, FUNC_ADPT_ARG(adapter), chbw_allow);
16183
16184
#ifdef CONFIG_MCC_MODE
16185
/* check setting success, don't go to ch union process */
16186
if (rtw_hal_set_mcc_setting_chk_start_clnt_join(adapter, &u_ch, &u_bw, &u_offset, chbw_allow))
16187
goto exit;
16188
#endif
16189
16190
if (chbw_allow == _TRUE) {
16191
rtw_sync_chbw(&cur_ch, &cur_bw, &cur_ch_offset, &u_ch, &u_bw, &u_offset);
16192
rtw_warn_on(cur_ch != pmlmeext->cur_channel);
16193
rtw_warn_on(cur_bw != pmlmeext->cur_bwmode);
16194
rtw_warn_on(cur_ch_offset != pmlmeext->cur_ch_offset);
16195
goto connect_allow_hdl;
16196
}
16197
16198
#ifdef CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT
16199
/* chbw_allow is _FALSE, connect allow? */
16200
for (i = 0; i < dvobj->iface_nums; i++) {
16201
iface = dvobj->padapters[i];
16202
mlme = &iface->mlmepriv;
16203
mlmeext = &iface->mlmeextpriv;
16204
16205
if (check_fwstate(mlme, WIFI_STATION_STATE)
16206
&& check_fwstate(mlme, WIFI_ASOC_STATE)
16207
#if defined(CONFIG_P2P)
16208
&& rtw_p2p_chk_state(&(iface->wdinfo), P2P_STATE_NONE)
16209
#endif
16210
) {
16211
connect_allow = _FALSE;
16212
break;
16213
}
16214
}
16215
#endif /* CONFIG_CFG80211_ONECHANNEL_UNDER_CONCURRENT */
16216
16217
if (MSTATE_STA_LD_NUM(&mstate) + MSTATE_AP_LD_NUM(&mstate) + MSTATE_MESH_LD_NUM(&mstate) >= 4)
16218
connect_allow = _FALSE;
16219
16220
RTW_INFO(FUNC_ADPT_FMT" connect_allow:%d\n"
16221
, FUNC_ADPT_ARG(adapter), connect_allow);
16222
16223
if (connect_allow == _FALSE)
16224
goto exit;
16225
16226
connect_allow_hdl:
16227
/* connect_allow == _TRUE */
16228
16229
if (chbw_allow == _FALSE) {
16230
u_ch = cur_ch;
16231
u_bw = cur_bw;
16232
u_offset = cur_ch_offset;
16233
16234
for (i = 0; i < dvobj->iface_nums; i++) {
16235
iface = dvobj->padapters[i];
16236
mlme = &iface->mlmepriv;
16237
mlmeext = &iface->mlmeextpriv;
16238
16239
if (!iface || iface == adapter)
16240
continue;
16241
16242
if ((MLME_IS_AP(iface) || MLME_IS_MESH(iface))
16243
&& check_fwstate(mlme, WIFI_ASOC_STATE)
16244
) {
16245
#ifdef CONFIG_SPCT_CH_SWITCH
16246
if (1)
16247
rtw_ap_inform_ch_switch(iface, pmlmeext->cur_channel , pmlmeext->cur_ch_offset);
16248
else
16249
#endif
16250
rtw_sta_flush(iface, _FALSE);
16251
16252
rtw_hal_set_hwreg(iface, HW_VAR_CHECK_TXBUF, 0);
16253
set_fwstate(mlme, WIFI_OP_CH_SWITCHING);
16254
16255
} else if (check_fwstate(mlme, WIFI_STATION_STATE)
16256
&& check_fwstate(mlme, WIFI_ASOC_STATE)
16257
) {
16258
rtw_disassoc_cmd(iface, 500, RTW_CMDF_DIRECTLY);
16259
rtw_indicate_disconnect(iface, 0, _FALSE);
16260
rtw_free_assoc_resources(iface, _TRUE);
16261
}
16262
}
16263
}
16264
16265
#ifdef CONFIG_DFS_MASTER
16266
rtw_dfs_rd_en_decision(adapter, MLME_STA_CONNECTING, 0);
16267
#endif
16268
}
16269
#endif /* CONFIG_CONCURRENT_MODE */
16270
16271
exit:
16272
16273
if (connect_allow == _TRUE) {
16274
RTW_INFO(FUNC_ADPT_FMT" union: %u,%u,%u\n", FUNC_ADPT_ARG(adapter), u_ch, u_bw, u_offset);
16275
*ch = u_ch;
16276
*bw = u_bw;
16277
*offset = u_offset;
16278
16279
#if defined(CONFIG_IOCTL_CFG80211) && (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0))
16280
{
16281
u8 ht_option = 0;
16282
16283
#ifdef CONFIG_80211N_HT
16284
ht_option = adapter->mlmepriv.htpriv.ht_option;
16285
#endif /* CONFIG_80211N_HT */
16286
16287
/*
16288
when supplicant send the mlme frame,
16289
the bss freq is updated by channel switch event.
16290
*/
16291
rtw_cfg80211_ch_switch_notify(adapter,
16292
cur_ch, cur_bw, cur_ch_offset, ht_option, 1);
16293
}
16294
#endif
16295
}
16296
16297
return connect_allow == _TRUE ? _SUCCESS : _FAIL;
16298
}
16299
16300
void rtw_set_external_auth_status(_adapter *padapter,
16301
const void *data, int len)
16302
{
16303
#ifdef CONFIG_IOCTL_CFG80211
16304
struct net_device *dev = padapter->pnetdev;
16305
struct wiphy *wiphy = adapter_to_wiphy(padapter);
16306
struct rtw_external_auth_params params;
16307
16308
/* convert data to external_auth_params */
16309
params.action = RTW_GET_BE32((u8 *)data);
16310
_rtw_memcpy(&params.bssid, (u8 *)data + 4, ETH_ALEN);
16311
_rtw_memcpy(&params.ssid.ssid, (u8 *)data + 10, WLAN_SSID_MAXLEN);
16312
params.ssid.ssid_len = RTW_GET_BE64((u8 *)data + 42);
16313
params.key_mgmt_suite = RTW_GET_BE32((u8 *)data + 58);
16314
params.status = RTW_GET_BE16((u8 *)data + 62);
16315
_rtw_memcpy(&params.pmkid, (u8 *)data + 64, PMKID_LEN);
16316
16317
rtw_cfg80211_external_auth_status(wiphy, dev, &params);
16318
#endif /* CONFIG_IOCTL_CFG80211 */
16319
}
16320
16321
u8 rtw_set_chbw_hdl(_adapter *padapter, u8 *pbuf)
16322
{
16323
struct set_ch_parm *set_ch_parm;
16324
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
16325
16326
if (!pbuf)
16327
return H2C_PARAMETERS_ERROR;
16328
16329
set_ch_parm = (struct set_ch_parm *)pbuf;
16330
16331
RTW_INFO(FUNC_NDEV_FMT" ch:%u, bw:%u, ch_offset:%u\n",
16332
FUNC_NDEV_ARG(padapter->pnetdev),
16333
set_ch_parm->ch, set_ch_parm->bw, set_ch_parm->ch_offset);
16334
16335
pmlmeext->cur_channel = set_ch_parm->ch;
16336
pmlmeext->cur_ch_offset = set_ch_parm->ch_offset;
16337
pmlmeext->cur_bwmode = set_ch_parm->bw;
16338
16339
set_channel_bwmode(padapter, set_ch_parm->ch, set_ch_parm->ch_offset, set_ch_parm->bw);
16340
16341
return H2C_SUCCESS;
16342
}
16343
16344
u8 set_chplan_hdl(_adapter *padapter, unsigned char *pbuf)
16345
{
16346
struct SetChannelPlan_param *setChannelPlan_param;
16347
struct rf_ctl_t *rfctl = adapter_to_rfctl(padapter);
16348
16349
if (!pbuf)
16350
return H2C_PARAMETERS_ERROR;
16351
16352
setChannelPlan_param = (struct SetChannelPlan_param *)pbuf;
16353
16354
if (!rtw_is_channel_plan_valid(setChannelPlan_param->channel_plan))
16355
return H2C_PARAMETERS_ERROR;
16356
16357
rfctl->country_ent = setChannelPlan_param->country_ent;
16358
rfctl->ChannelPlan = setChannelPlan_param->channel_plan;
16359
16360
rfctl->max_chan_nums = init_channel_set(padapter, rfctl->ChannelPlan, rfctl->channel_set);
16361
init_channel_list(padapter, rfctl->channel_set, &rfctl->channel_list);
16362
#if CONFIG_TXPWR_LIMIT
16363
rtw_txpwr_init_regd(rfctl);
16364
#endif
16365
16366
rtw_hal_set_odm_var(padapter, HAL_ODM_REGULATION, NULL, _TRUE);
16367
16368
#ifdef CONFIG_IOCTL_CFG80211
16369
rtw_regd_apply_flags(adapter_to_wiphy(padapter));
16370
#endif
16371
16372
return H2C_SUCCESS;
16373
}
16374
16375
u8 led_blink_hdl(_adapter *padapter, unsigned char *pbuf)
16376
{
16377
struct LedBlink_param *ledBlink_param;
16378
16379
if (!pbuf)
16380
return H2C_PARAMETERS_ERROR;
16381
16382
ledBlink_param = (struct LedBlink_param *)pbuf;
16383
16384
#ifdef CONFIG_RTW_LED_HANDLED_BY_CMD_THREAD
16385
BlinkHandler((PLED_DATA)ledBlink_param->pLed);
16386
#endif
16387
16388
return H2C_SUCCESS;
16389
}
16390
16391
u8 set_csa_hdl(_adapter *adapter, unsigned char *pbuf)
16392
{
16393
#ifdef CONFIG_DFS
16394
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
16395
16396
if (rfctl->csa_ch)
16397
rtw_dfs_ch_switch_hdl(adapter_to_dvobj(adapter));
16398
#endif
16399
return H2C_SUCCESS;
16400
}
16401
16402
u8 tdls_hdl(_adapter *padapter, unsigned char *pbuf)
16403
{
16404
#ifdef CONFIG_TDLS
16405
_irqL irqL;
16406
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
16407
struct tdls_info *ptdlsinfo = &padapter->tdlsinfo;
16408
#ifdef CONFIG_TDLS_CH_SW
16409
struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
16410
#endif
16411
struct TDLSoption_param *TDLSoption;
16412
struct sta_info *ptdls_sta = NULL;
16413
struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
16414
struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
16415
struct sta_info *ap_sta = rtw_get_stainfo(&padapter->stapriv, get_my_bssid(&(pmlmeinfo->network)));
16416
u8 survey_channel, i, min, option;
16417
struct tdls_txmgmt txmgmt;
16418
u32 setchtime, resp_sleep = 0, wait_time;
16419
u8 zaddr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
16420
u8 ret;
16421
u8 doiqk;
16422
u64 tx_ra_bitmap = 0;
16423
16424
if (!pbuf)
16425
return H2C_PARAMETERS_ERROR;
16426
16427
TDLSoption = (struct TDLSoption_param *)pbuf;
16428
option = TDLSoption->option;
16429
16430
if (!_rtw_memcmp(TDLSoption->addr, zaddr, ETH_ALEN)) {
16431
ptdls_sta = rtw_get_stainfo(&(padapter->stapriv), TDLSoption->addr);
16432
if (ptdls_sta == NULL)
16433
return H2C_REJECTED;
16434
} else {
16435
if (!(option == TDLS_RS_RCR))
16436
return H2C_REJECTED;
16437
}
16438
16439
/* _enter_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
16440
/* RTW_INFO("[%s] option:%d\n", __FUNCTION__, option); */
16441
16442
switch (option) {
16443
case TDLS_ESTABLISHED: {
16444
/* As long as TDLS handshake success, we should set RCR_CBSSID_DATA bit to 0 */
16445
/* So we can receive all kinds of data frames. */
16446
u8 sta_band = 0;
16447
16448
/* leave ALL PS when TDLS is established */
16449
rtw_pwr_wakeup(padapter);
16450
16451
rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_LINKED);
16452
RTW_INFO("Created Direct Link with "MAC_FMT"\n", MAC_ARG(ptdls_sta->cmn.mac_addr));
16453
16454
/* Set TDLS sta rate. */
16455
/* Update station supportRate */
16456
rtw_hal_update_sta_ra_info(padapter, ptdls_sta);
16457
tx_ra_bitmap = ptdls_sta->cmn.ra_info.ramask;
16458
16459
if (pmlmeext->cur_channel > 14) {
16460
if (tx_ra_bitmap & 0xffff000)
16461
sta_band |= WIRELESS_11_5N ;
16462
16463
if (tx_ra_bitmap & 0xff0)
16464
sta_band |= WIRELESS_11A;
16465
16466
/* 5G band */
16467
#ifdef CONFIG_80211AC_VHT
16468
if (ptdls_sta->vhtpriv.vht_option)
16469
sta_band = WIRELESS_11_5AC;
16470
#endif
16471
16472
} else {
16473
if (tx_ra_bitmap & 0xffff000)
16474
sta_band |= WIRELESS_11_24N;
16475
16476
if (tx_ra_bitmap & 0xff0)
16477
sta_band |= WIRELESS_11G;
16478
16479
if (tx_ra_bitmap & 0x0f)
16480
sta_band |= WIRELESS_11B;
16481
}
16482
ptdls_sta->wireless_mode = sta_band;
16483
rtw_hal_update_sta_wset(padapter, ptdls_sta);
16484
/* Sta mode */
16485
rtw_hal_set_odm_var(padapter, HAL_ODM_STA_INFO, ptdls_sta, _TRUE);
16486
16487
set_sta_rate(padapter, ptdls_sta);
16488
rtw_sta_media_status_rpt(padapter, ptdls_sta, 1);
16489
break;
16490
}
16491
case TDLS_ISSUE_PTI:
16492
ptdls_sta->tdls_sta_state |= TDLS_WAIT_PTR_STATE;
16493
issue_tdls_peer_traffic_indication(padapter, ptdls_sta);
16494
_set_timer(&ptdls_sta->pti_timer, TDLS_PTI_TIME);
16495
break;
16496
#ifdef CONFIG_TDLS_CH_SW
16497
case TDLS_CH_SW_RESP:
16498
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
16499
txmgmt.status_code = 0;
16500
_rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
16501
16502
if (ap_sta)
16503
rtw_hal_macid_sleep(padapter, ap_sta->cmn.mac_id);
16504
issue_nulldata(padapter, NULL, 1, 3, 3);
16505
16506
RTW_INFO("[TDLS ] issue tdls channel switch response\n");
16507
ret = issue_tdls_ch_switch_rsp(padapter, &txmgmt, _TRUE);
16508
16509
/* If we receive TDLS_CH_SW_REQ at off channel which it's target is AP's channel */
16510
/* then we just switch to AP's channel*/
16511
if (padapter->mlmeextpriv.cur_channel == pchsw_info->off_ch_num) {
16512
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_END_TO_BASE_CHNL);
16513
break;
16514
}
16515
16516
if (ret == _SUCCESS)
16517
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_OFF_CHNL);
16518
else
16519
RTW_INFO("[TDLS] issue_tdls_ch_switch_rsp wait ack fail !!!!!!!!!!\n");
16520
16521
break;
16522
case TDLS_CH_SW_PREPARE:
16523
pchsw_info->ch_sw_state |= TDLS_CH_SWITCH_PREPARE_STATE;
16524
16525
/* to collect IQK info of off-chnl */
16526
doiqk = _TRUE;
16527
rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
16528
set_channel_bwmode(padapter, pchsw_info->off_ch_num, pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20);
16529
doiqk = _FALSE;
16530
rtw_hal_set_hwreg(padapter, HW_VAR_DO_IQK, &doiqk);
16531
16532
/* switch back to base-chnl */
16533
set_channel_bwmode(padapter, pmlmeext->cur_channel, pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode);
16534
16535
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_START);
16536
16537
pchsw_info->ch_sw_state &= ~(TDLS_CH_SWITCH_PREPARE_STATE);
16538
16539
break;
16540
case TDLS_CH_SW_START:
16541
rtw_tdls_set_ch_sw_oper_control(padapter, _TRUE);
16542
break;
16543
case TDLS_CH_SW_TO_OFF_CHNL:
16544
if (ap_sta)
16545
rtw_hal_macid_sleep(padapter, ap_sta->cmn.mac_id);
16546
issue_nulldata(padapter, NULL, 1, 3, 3);
16547
16548
if (padapter->registrypriv.wifi_spec == 0) {
16549
if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
16550
_set_timer(&ptdls_sta->ch_sw_timer, (u32)(ptdls_sta->ch_switch_timeout) / 1000);
16551
}
16552
16553
if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_OFF_CHNL, pchsw_info->off_ch_num,
16554
pchsw_info->ch_offset, (pchsw_info->ch_offset) ? CHANNEL_WIDTH_40 : CHANNEL_WIDTH_20, ptdls_sta->ch_switch_time) == _SUCCESS) {
16555
pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE);
16556
if (pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE) {
16557
if (issue_nulldata_to_TDLS_peer_STA(ptdls_sta->padapter, ptdls_sta->cmn.mac_addr, 0, 1,
16558
(padapter->registrypriv.wifi_spec == 0) ? 3 : 0) == _FAIL)
16559
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
16560
}
16561
} else {
16562
if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
16563
_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
16564
}
16565
16566
16567
break;
16568
case TDLS_CH_SW_END:
16569
case TDLS_CH_SW_END_TO_BASE_CHNL:
16570
rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
16571
_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
16572
_cancel_timer_ex(&ptdls_sta->stay_on_base_chnl_timer);
16573
_cancel_timer_ex(&ptdls_sta->ch_sw_monitor_timer);
16574
#if 0
16575
_rtw_memset(pHalData->tdls_ch_sw_iqk_info_base_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_base_chnl));
16576
_rtw_memset(pHalData->tdls_ch_sw_iqk_info_off_chnl, 0x00, sizeof(pHalData->tdls_ch_sw_iqk_info_off_chnl));
16577
#endif
16578
16579
if (option == TDLS_CH_SW_END_TO_BASE_CHNL)
16580
rtw_tdls_cmd(padapter, ptdls_sta->cmn.mac_addr, TDLS_CH_SW_TO_BASE_CHNL);
16581
16582
break;
16583
case TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED:
16584
case TDLS_CH_SW_TO_BASE_CHNL:
16585
pchsw_info->ch_sw_state &= ~(TDLS_PEER_AT_OFF_STATE | TDLS_WAIT_CH_RSP_STATE);
16586
16587
if (option == TDLS_CH_SW_TO_BASE_CHNL_UNSOLICITED) {
16588
if (ptdls_sta != NULL) {
16589
/* Send unsolicited channel switch rsp. to peer */
16590
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
16591
txmgmt.status_code = 0;
16592
_rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
16593
issue_tdls_ch_switch_rsp(padapter, &txmgmt, _FALSE);
16594
}
16595
}
16596
16597
if (rtw_tdls_do_ch_sw(padapter, ptdls_sta, TDLS_CH_SW_BASE_CHNL, pmlmeext->cur_channel,
16598
pmlmeext->cur_ch_offset, pmlmeext->cur_bwmode, ptdls_sta->ch_switch_time) == _SUCCESS) {
16599
if (ap_sta)
16600
rtw_hal_macid_wakeup(padapter, ap_sta->cmn.mac_id);
16601
issue_nulldata(padapter, NULL, 0, 3, 3);
16602
/* set ch sw monitor timer for responder */
16603
if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
16604
_set_timer(&ptdls_sta->ch_sw_monitor_timer, TDLS_CH_SW_MONITOR_TIMEOUT);
16605
}
16606
16607
break;
16608
#endif
16609
case TDLS_RS_RCR:
16610
rtw_hal_rcr_set_chk_bssid(padapter, MLME_TDLS_NOLINK);
16611
break;
16612
case TDLS_TEARDOWN_STA:
16613
case TDLS_TEARDOWN_STA_NO_WAIT:
16614
_rtw_memset(&txmgmt, 0x00, sizeof(struct tdls_txmgmt));
16615
txmgmt.status_code = _RSON_TDLS_TEAR_UN_RSN_;
16616
_rtw_memcpy(txmgmt.peer, ptdls_sta->cmn.mac_addr, ETH_ALEN);
16617
16618
issue_tdls_teardown(padapter, &txmgmt, (option == TDLS_TEARDOWN_STA) ? _TRUE : _FALSE);
16619
16620
break;
16621
case TDLS_TEARDOWN_STA_LOCALLY:
16622
case TDLS_TEARDOWN_STA_LOCALLY_POST:
16623
#ifdef CONFIG_TDLS_CH_SW
16624
if (_rtw_memcmp(TDLSoption->addr, pchsw_info->addr, ETH_ALEN) == _TRUE) {
16625
pchsw_info->ch_sw_state &= ~(TDLS_CH_SW_INITIATOR_STATE |
16626
TDLS_CH_SWITCH_ON_STATE |
16627
TDLS_PEER_AT_OFF_STATE);
16628
rtw_tdls_set_ch_sw_oper_control(padapter, _FALSE);
16629
_rtw_memset(pchsw_info->addr, 0x00, ETH_ALEN);
16630
}
16631
#endif
16632
16633
if (option == TDLS_TEARDOWN_STA_LOCALLY)
16634
rtw_tdls_teardown_pre_hdl(padapter, ptdls_sta);
16635
16636
rtw_tdls_teardown_post_hdl(padapter, ptdls_sta, _FALSE);
16637
16638
if (ptdlsinfo->tdls_sctx != NULL)
16639
rtw_sctx_done(&(ptdlsinfo->tdls_sctx));
16640
16641
break;
16642
}
16643
16644
/* _exit_critical_bh(&(ptdlsinfo->hdl_lock), &irqL); */
16645
16646
return H2C_SUCCESS;
16647
#else
16648
return H2C_REJECTED;
16649
#endif /* CONFIG_TDLS */
16650
16651
}
16652
16653
u8 run_in_thread_hdl(_adapter *padapter, u8 *pbuf)
16654
{
16655
struct RunInThread_param *p;
16656
16657
16658
if (NULL == pbuf)
16659
return H2C_PARAMETERS_ERROR;
16660
p = (struct RunInThread_param *)pbuf;
16661
16662
if (p->func)
16663
p->func(p->context);
16664
16665
return H2C_SUCCESS;
16666
}
16667
16668
u8 rtw_getmacreg_hdl(_adapter *padapter, u8 *pbuf)
16669
{
16670
16671
struct readMAC_parm *preadmacparm = NULL;
16672
u8 sz = 0;
16673
u32 addr = 0;
16674
u32 value = 0;
16675
16676
if (!pbuf)
16677
return H2C_PARAMETERS_ERROR;
16678
16679
preadmacparm = (struct readMAC_parm *) pbuf;
16680
sz = preadmacparm->len;
16681
addr = preadmacparm->addr;
16682
value = 0;
16683
16684
switch (sz) {
16685
case 1:
16686
value = rtw_read8(padapter, addr);
16687
break;
16688
case 2:
16689
value = rtw_read16(padapter, addr);
16690
break;
16691
case 4:
16692
value = rtw_read32(padapter, addr);
16693
break;
16694
default:
16695
RTW_INFO("%s: Unknown size\n", __func__);
16696
break;
16697
}
16698
RTW_INFO("%s: addr:0x%02x valeu:0x%02x\n", __func__, addr, value);
16699
16700
return H2C_SUCCESS;
16701
}
16702
16703
int rtw_sae_preprocess(_adapter *adapter, const u8 *buf, u32 len, u8 tx)
16704
{
16705
#ifdef CONFIG_IOCTL_CFG80211
16706
const u8 *frame_body = buf + sizeof(struct rtw_ieee80211_hdr_3addr);
16707
u16 alg;
16708
u16 seq;
16709
u16 status;
16710
int ret = _FAIL;
16711
16712
alg = RTW_GET_LE16(frame_body);
16713
if (alg != WLAN_AUTH_SAE)
16714
goto exit;
16715
16716
seq = RTW_GET_LE16(frame_body + 2);
16717
status = RTW_GET_LE16(frame_body + 4);
16718
16719
RTW_INFO("RTW_%s:AUTH alg:0x%04x, seq:0x%04x, status:0x%04x, mesg:%s\n",
16720
(tx == _TRUE) ? "Tx" : "Rx", alg, seq, status,
16721
(seq == 1) ? "Commit" : "Confirm");
16722
16723
ret = _SUCCESS;
16724
16725
#ifdef CONFIG_RTW_MESH
16726
if (MLME_IS_MESH(adapter)) {
16727
rtw_mesh_sae_check_frames(adapter, buf, len, tx, alg, seq, status);
16728
goto exit;
16729
}
16730
#endif
16731
16732
if (tx && (seq == 2) && (status == 0)) {
16733
/* quere commit frame until external auth statue update */
16734
struct sta_priv *pstapriv = &adapter->stapriv;
16735
struct sta_info *psta = NULL;
16736
_irqL irqL;
16737
16738
psta = rtw_get_stainfo(pstapriv, GetAddr1Ptr(buf));
16739
if (psta) {
16740
_enter_critical_bh(&psta->lock, &irqL);
16741
if (psta->pauth_frame) {
16742
rtw_mfree(psta->pauth_frame, psta->auth_len);
16743
psta->pauth_frame = NULL;
16744
psta->auth_len = 0;
16745
}
16746
16747
psta->pauth_frame = rtw_zmalloc(len);
16748
if (psta->pauth_frame) {
16749
_rtw_memcpy(psta->pauth_frame, buf, len);
16750
psta->auth_len = len;
16751
}
16752
_exit_critical_bh(&psta->lock, &irqL);
16753
16754
ret = 2;
16755
}
16756
}
16757
exit:
16758
return ret;
16759
#else
16760
return _SUCCESS;
16761
#endif /* CONFIG_IOCTL_CFG80211 */
16762
}
16763
16764
16765