Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/core/mesh/rtw_mesh.c
1307 views
1
/******************************************************************************
2
*
3
* Copyright(c) 2007 - 2017 Realtek Corporation.
4
*
5
* This program is free software; you can redistribute it and/or modify it
6
* under the terms of version 2 of the GNU General Public License as
7
* published by the Free Software Foundation.
8
*
9
* This program is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
* more details.
13
*
14
*****************************************************************************/
15
#define _RTW_MESH_C_
16
17
#ifdef CONFIG_RTW_MESH
18
#include <drv_types.h>
19
20
const char *_rtw_mesh_plink_str[] = {
21
"UNKNOWN",
22
"LISTEN",
23
"OPN_SNT",
24
"OPN_RCVD",
25
"CNF_RCVD",
26
"ESTAB",
27
"HOLDING",
28
"BLOCKED",
29
};
30
31
const char *_rtw_mesh_ps_str[] = {
32
"UNKNOWN",
33
"ACTIVE",
34
"LSLEEP",
35
"DSLEEP",
36
};
37
38
const char *_action_self_protected_str[] = {
39
"ACT_SELF_PROTECTED_RSVD",
40
"MESH_OPEN",
41
"MESH_CONF",
42
"MESH_CLOSE",
43
"MESH_GK_INFORM",
44
"MESH_GK_ACK",
45
};
46
47
inline u8 *rtw_set_ie_mesh_id(u8 *buf, u32 *buf_len, const char *mesh_id, u8 id_len)
48
{
49
return rtw_set_ie(buf, WLAN_EID_MESH_ID, id_len, mesh_id, buf_len);
50
}
51
52
inline u8 *rtw_set_ie_mesh_config(u8 *buf, u32 *buf_len
53
, u8 path_sel_proto, u8 path_sel_metric, u8 congest_ctl_mode, u8 sync_method, u8 auth_proto
54
, u8 num_of_peerings, bool cto_mgate, bool cto_as
55
, bool accept_peerings, bool mcca_sup, bool mcca_en, bool forwarding
56
, bool mbca_en, bool tbtt_adj, bool ps_level)
57
{
58
59
u8 conf[7] = {0};
60
61
SET_MESH_CONF_ELE_PATH_SEL_PROTO_ID(conf, path_sel_proto);
62
SET_MESH_CONF_ELE_PATH_SEL_METRIC_ID(conf, path_sel_metric);
63
SET_MESH_CONF_ELE_CONGEST_CTRL_MODE_ID(conf, congest_ctl_mode);
64
SET_MESH_CONF_ELE_SYNC_METHOD_ID(conf, sync_method);
65
SET_MESH_CONF_ELE_AUTH_PROTO_ID(conf, auth_proto);
66
67
SET_MESH_CONF_ELE_CTO_MGATE(conf, cto_mgate);
68
SET_MESH_CONF_ELE_NUM_OF_PEERINGS(conf, num_of_peerings);
69
SET_MESH_CONF_ELE_CTO_AS(conf, cto_as);
70
71
SET_MESH_CONF_ELE_ACCEPT_PEERINGS(conf, accept_peerings);
72
SET_MESH_CONF_ELE_MCCA_SUP(conf, mcca_sup);
73
SET_MESH_CONF_ELE_MCCA_EN(conf, mcca_en);
74
SET_MESH_CONF_ELE_FORWARDING(conf, forwarding);
75
SET_MESH_CONF_ELE_MBCA_EN(conf, mbca_en);
76
SET_MESH_CONF_ELE_TBTT_ADJ(conf, tbtt_adj);
77
SET_MESH_CONF_ELE_PS_LEVEL(conf, ps_level);
78
79
return rtw_set_ie(buf, WLAN_EID_MESH_CONFIG, 7, conf, buf_len);
80
}
81
82
inline u8 *rtw_set_ie_mpm(u8 *buf, u32 *buf_len
83
, u8 proto_id, u16 llid, u16 *plid, u16 *reason, u8 *chosen_pmk)
84
{
85
u8 data[24] = {0};
86
u8 *pos = data;
87
88
RTW_PUT_LE16(pos, proto_id);
89
pos += 2;
90
91
RTW_PUT_LE16(pos, llid);
92
pos += 2;
93
94
if (plid) {
95
RTW_PUT_LE16(pos, *plid);
96
pos += 2;
97
}
98
99
if (reason) {
100
RTW_PUT_LE16(pos, *reason);
101
pos += 2;
102
}
103
104
if (chosen_pmk) {
105
_rtw_memcpy(pos, chosen_pmk, 16);
106
pos += 16;
107
}
108
109
return rtw_set_ie(buf, WLAN_EID_MPM, pos - data, data, buf_len);
110
}
111
112
bool rtw_bss_is_forwarding(WLAN_BSSID_EX *bss)
113
{
114
u8 *ie;
115
int ie_len;
116
bool ret = 0;
117
118
ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
119
BSS_EX_TLV_IES_LEN(bss));
120
if (!ie || ie_len != 7)
121
goto exit;
122
123
ret = GET_MESH_CONF_ELE_FORWARDING(ie + 2);
124
125
exit:
126
return ret;
127
}
128
129
bool rtw_bss_is_cto_mgate(WLAN_BSSID_EX *bss)
130
{
131
u8 *ie;
132
int ie_len;
133
bool ret = 0;
134
135
ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
136
BSS_EX_TLV_IES_LEN(bss));
137
if (!ie || ie_len != 7)
138
goto exit;
139
140
ret = GET_MESH_CONF_ELE_CTO_MGATE(ie + 2);
141
142
exit:
143
return ret;
144
}
145
146
int rtw_bss_is_same_mbss(WLAN_BSSID_EX *a, WLAN_BSSID_EX *b)
147
{
148
int ret = 0;
149
u8 *a_mconf_ie, *b_mconf_ie;
150
sint a_mconf_ie_len, b_mconf_ie_len;
151
152
if (a->InfrastructureMode != Ndis802_11_mesh)
153
goto exit;
154
a_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(a), WLAN_EID_MESH_CONFIG, &a_mconf_ie_len, BSS_EX_TLV_IES_LEN(a));
155
if (!a_mconf_ie || a_mconf_ie_len != 7)
156
goto exit;
157
if (b->InfrastructureMode != Ndis802_11_mesh)
158
goto exit;
159
b_mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(b), WLAN_EID_MESH_CONFIG, &b_mconf_ie_len, BSS_EX_TLV_IES_LEN(b));
160
if (!b_mconf_ie || b_mconf_ie_len != 7)
161
goto exit;
162
163
if (a->mesh_id.SsidLength != b->mesh_id.SsidLength
164
|| _rtw_memcmp(a->mesh_id.Ssid, b->mesh_id.Ssid, a->mesh_id.SsidLength) == _FALSE)
165
goto exit;
166
167
if (_rtw_memcmp(a_mconf_ie + 2, b_mconf_ie + 2, 5) == _FALSE)
168
goto exit;
169
170
ret = 1;
171
172
exit:
173
return ret;
174
}
175
176
int rtw_bss_is_candidate_mesh_peer(WLAN_BSSID_EX *self, WLAN_BSSID_EX *target, u8 ch, u8 add_peer)
177
{
178
int ret = 0;
179
u8 *mconf_ie;
180
sint mconf_ie_len;
181
int i, j;
182
183
if (!rtw_bss_is_same_mbss(self, target))
184
goto exit;
185
186
if (ch && self->Configuration.DSConfig != target->Configuration.DSConfig)
187
goto exit;
188
189
if (add_peer) {
190
/* Accept additional mesh peerings */
191
mconf_ie = rtw_get_ie(BSS_EX_TLV_IES(target), WLAN_EID_MESH_CONFIG, &mconf_ie_len, BSS_EX_TLV_IES_LEN(target));
192
if (!mconf_ie || mconf_ie_len != 7)
193
goto exit;
194
if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mconf_ie + 2) == 0)
195
goto exit;
196
}
197
198
/* BSSBasicRateSet */
199
for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
200
if (target->SupportedRates[i] == 0)
201
break;
202
if (target->SupportedRates[i] & 0x80) {
203
u8 match = 0;
204
205
if (!ch) {
206
/* off-channel, check target with our hardcode capability */
207
if (target->Configuration.DSConfig > 14)
208
match = rtw_is_basic_rate_ofdm(target->SupportedRates[i]);
209
else
210
match = rtw_is_basic_rate_mix(target->SupportedRates[i]);
211
} else {
212
for (j = 0; j < NDIS_802_11_LENGTH_RATES_EX; j++) {
213
if (self->SupportedRates[j] == 0)
214
break;
215
if (self->SupportedRates[j] == target->SupportedRates[i]) {
216
match = 1;
217
break;
218
}
219
}
220
}
221
if (!match)
222
goto exit;
223
}
224
}
225
226
/* BSSBasicMCSSet */
227
228
/* 802.1X connected to AS ? */
229
230
ret = 1;
231
232
exit:
233
return ret;
234
}
235
236
void rtw_mesh_bss_peering_status(WLAN_BSSID_EX *bss, u8 *nop, u8 *accept)
237
{
238
u8 *ie;
239
int ie_len;
240
241
if (nop)
242
*nop = 0;
243
if (accept)
244
*accept = 0;
245
246
ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
247
BSS_EX_TLV_IES_LEN(bss));
248
if (!ie || ie_len != 7)
249
goto exit;
250
251
if (nop)
252
*nop = GET_MESH_CONF_ELE_NUM_OF_PEERINGS(ie + 2);
253
if (accept)
254
*accept = GET_MESH_CONF_ELE_ACCEPT_PEERINGS(ie + 2);
255
256
exit:
257
return;
258
}
259
260
#if CONFIG_RTW_MESH_ACNODE_PREVENT
261
void rtw_mesh_update_scanned_acnode_status(_adapter *adapter, struct wlan_network *scanned)
262
{
263
bool acnode;
264
u8 nop, accept;
265
266
rtw_mesh_bss_peering_status(&scanned->network, &nop, &accept);
267
268
acnode = !nop && accept;
269
270
if (acnode && scanned->acnode_stime == 0) {
271
scanned->acnode_stime = rtw_get_current_time();
272
if (scanned->acnode_stime == 0)
273
scanned->acnode_stime++;
274
} else if (!acnode) {
275
scanned->acnode_stime = 0;
276
scanned->acnode_notify_etime = 0;
277
}
278
}
279
280
bool rtw_mesh_scanned_is_acnode_confirmed(_adapter *adapter, struct wlan_network *scanned)
281
{
282
return scanned->acnode_stime
283
&& rtw_get_passing_time_ms(scanned->acnode_stime)
284
> adapter->mesh_cfg.peer_sel_policy.acnode_conf_timeout_ms;
285
}
286
287
static bool rtw_mesh_scanned_is_acnode_allow_notify(_adapter *adapter, struct wlan_network *scanned)
288
{
289
return scanned->acnode_notify_etime
290
&& rtw_time_after(scanned->acnode_notify_etime, rtw_get_current_time());
291
}
292
293
bool rtw_mesh_acnode_prevent_allow_sacrifice(_adapter *adapter)
294
{
295
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
296
struct sta_priv *stapriv = &adapter->stapriv;
297
bool allow = 0;
298
299
if (!mcfg->peer_sel_policy.acnode_prevent
300
|| mcfg->max_peer_links <= 1
301
|| stapriv->asoc_list_cnt < mcfg->max_peer_links)
302
goto exit;
303
304
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
305
if (rtw_mesh_cto_mgate_required(adapter))
306
goto exit;
307
#endif
308
309
allow = 1;
310
311
exit:
312
return allow;
313
}
314
315
static bool rtw_mesh_acnode_candidate_exist(_adapter *adapter)
316
{
317
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
318
struct sta_priv *stapriv = &adapter->stapriv;
319
struct mlme_priv *mlme = &adapter->mlmepriv;
320
_queue *queue = &(mlme->scanned_queue);
321
_list *head, *list;
322
_irqL irqL;
323
struct wlan_network *scanned = NULL;
324
struct sta_info *sta = NULL;
325
bool need = 0;
326
327
_enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
328
329
head = get_list_head(queue);
330
list = get_next(head);
331
while (!rtw_end_of_queue_search(head, list)) {
332
scanned = LIST_CONTAINOR(list, struct wlan_network, list);
333
list = get_next(list);
334
335
if (rtw_get_passing_time_ms(scanned->last_scanned) < mcfg->peer_sel_policy.scanr_exp_ms
336
&& rtw_mesh_scanned_is_acnode_confirmed(adapter, scanned)
337
&& (!mcfg->rssi_threshold || mcfg->rssi_threshold <= scanned->network.Rssi)
338
#if CONFIG_RTW_MACADDR_ACL
339
&& rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
340
#endif
341
&& rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
342
#if CONFIG_RTW_MESH_PEER_BLACKLIST
343
&& !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
344
#endif
345
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
346
&& rtw_mesh_cto_mgate_network_filter(adapter, scanned)
347
#endif
348
) {
349
need = 1;
350
break;
351
}
352
}
353
354
_exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
355
356
return need;
357
}
358
359
static int rtw_mesh_acnode_prevent_sacrifice_chk(_adapter *adapter, struct sta_info **sac, struct sta_info *com)
360
{
361
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
362
int updated = 0;
363
364
/*
365
* TODO: compare next_hop reference cnt of forwarding info
366
* don't sacrifice working next_hop or choose sta with least cnt
367
*/
368
369
if (*sac == NULL) {
370
updated = 1;
371
goto exit;
372
}
373
374
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
375
if (mcfg->peer_sel_policy.cto_mgate_require
376
&& !mcfg->dot11MeshGateAnnouncementProtocol
377
) {
378
if (IS_CTO_MGATE_CONF_TIMEOUT(com->plink)) {
379
if (!IS_CTO_MGATE_CONF_TIMEOUT((*sac)->plink)) {
380
/* blacklist > not blacklist */
381
updated = 1;
382
goto exit;
383
}
384
} else if (!IS_CTO_MGATE_CONF_DISABLED(com->plink)) {
385
if (IS_CTO_MGATE_CONF_DISABLED((*sac)->plink)) {
386
/* confirming > disabled */
387
updated = 1;
388
goto exit;
389
}
390
}
391
}
392
#endif
393
394
exit:
395
if (updated)
396
*sac = com;
397
398
return updated;
399
}
400
401
struct sta_info *_rtw_mesh_acnode_prevent_pick_sacrifice(_adapter *adapter)
402
{
403
struct sta_priv *stapriv = &adapter->stapriv;
404
_list *head, *list;
405
struct sta_info *sta, *sacrifice = NULL;
406
u8 nop;
407
408
head = &stapriv->asoc_list;
409
list = get_next(head);
410
while (rtw_end_of_queue_search(head, list) == _FALSE) {
411
sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
412
list = get_next(list);
413
414
if (!sta->plink || !sta->plink->scanned) {
415
rtw_warn_on(1);
416
continue;
417
}
418
419
rtw_mesh_bss_peering_status(&sta->plink->scanned->network, &nop, NULL);
420
if (nop < 2)
421
continue;
422
423
rtw_mesh_acnode_prevent_sacrifice_chk(adapter, &sacrifice, sta);
424
}
425
426
return sacrifice;
427
}
428
429
struct sta_info *rtw_mesh_acnode_prevent_pick_sacrifice(_adapter *adapter)
430
{
431
struct sta_priv *stapriv = &adapter->stapriv;
432
struct sta_info *sacrifice = NULL;
433
434
enter_critical_bh(&stapriv->asoc_list_lock);
435
436
sacrifice = _rtw_mesh_acnode_prevent_pick_sacrifice(adapter);
437
438
exit_critical_bh(&stapriv->asoc_list_lock);
439
440
return sacrifice;
441
}
442
443
static void rtw_mesh_acnode_rsvd_chk(_adapter *adapter)
444
{
445
struct rtw_mesh_info *minfo = &adapter->mesh_info;
446
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
447
u8 acnode_rsvd = 0;
448
449
if (rtw_mesh_acnode_prevent_allow_sacrifice(adapter)
450
&& rtw_mesh_acnode_prevent_pick_sacrifice(adapter)
451
&& rtw_mesh_acnode_candidate_exist(adapter))
452
acnode_rsvd = 1;
453
454
if (plink_ctl->acnode_rsvd != acnode_rsvd) {
455
plink_ctl->acnode_rsvd = acnode_rsvd;
456
RTW_INFO(FUNC_ADPT_FMT" acnode_rsvd = %d\n", FUNC_ADPT_ARG(adapter), plink_ctl->acnode_rsvd);
457
update_beacon(adapter, WLAN_EID_MESH_CONFIG, NULL, 1, 0);
458
}
459
}
460
461
static void rtw_mesh_acnode_set_notify_etime(_adapter *adapter, u8 *rframe_whdr)
462
{
463
if (adapter->mesh_info.plink_ctl.acnode_rsvd) {
464
struct wlan_network *scanned = rtw_find_network(&adapter->mlmepriv.scanned_queue, get_addr2_ptr(rframe_whdr));
465
466
if (rtw_mesh_scanned_is_acnode_confirmed(adapter, scanned)) {
467
scanned->acnode_notify_etime = rtw_get_current_time()
468
+ rtw_ms_to_systime(adapter->mesh_cfg.peer_sel_policy.acnode_notify_timeout_ms);
469
if (scanned->acnode_notify_etime == 0)
470
scanned->acnode_notify_etime++;
471
}
472
}
473
}
474
475
void dump_mesh_acnode_prevent_settings(void *sel, _adapter *adapter)
476
{
477
struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
478
479
RTW_PRINT_SEL(sel, "%-6s %-12s %-14s\n"
480
, "enable", "conf_timeout", "nofity_timeout");
481
RTW_PRINT_SEL(sel, "%6u %12u %14u\n"
482
, peer_sel_policy->acnode_prevent
483
, peer_sel_policy->acnode_conf_timeout_ms
484
, peer_sel_policy->acnode_notify_timeout_ms);
485
}
486
#endif /* CONFIG_RTW_MESH_ACNODE_PREVENT */
487
488
#if CONFIG_RTW_MESH_PEER_BLACKLIST
489
int rtw_mesh_peer_blacklist_add(_adapter *adapter, const u8 *addr)
490
{
491
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
492
struct rtw_mesh_info *minfo = &adapter->mesh_info;
493
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
494
495
return rtw_blacklist_add(&plink_ctl->peer_blacklist, addr
496
, mcfg->peer_sel_policy.peer_blacklist_timeout_ms);
497
}
498
499
int rtw_mesh_peer_blacklist_del(_adapter *adapter, const u8 *addr)
500
{
501
struct rtw_mesh_info *minfo = &adapter->mesh_info;
502
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
503
504
return rtw_blacklist_del(&plink_ctl->peer_blacklist, addr);
505
}
506
507
int rtw_mesh_peer_blacklist_search(_adapter *adapter, const u8 *addr)
508
{
509
struct rtw_mesh_info *minfo = &adapter->mesh_info;
510
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
511
512
return rtw_blacklist_search(&plink_ctl->peer_blacklist, addr);
513
}
514
515
void rtw_mesh_peer_blacklist_flush(_adapter *adapter)
516
{
517
struct rtw_mesh_info *minfo = &adapter->mesh_info;
518
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
519
520
rtw_blacklist_flush(&plink_ctl->peer_blacklist);
521
}
522
523
void dump_mesh_peer_blacklist(void *sel, _adapter *adapter)
524
{
525
struct rtw_mesh_info *minfo = &adapter->mesh_info;
526
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
527
528
dump_blacklist(sel, &plink_ctl->peer_blacklist, "blacklist");
529
}
530
531
void dump_mesh_peer_blacklist_settings(void *sel, _adapter *adapter)
532
{
533
struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
534
535
RTW_PRINT_SEL(sel, "%-12s %-17s\n"
536
, "conf_timeout", "blacklist_timeout");
537
RTW_PRINT_SEL(sel, "%12u %17u\n"
538
, peer_sel_policy->peer_conf_timeout_ms
539
, peer_sel_policy->peer_blacklist_timeout_ms);
540
}
541
#endif /* CONFIG_RTW_MESH_PEER_BLACKLIST */
542
543
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
544
u8 rtw_mesh_cto_mgate_required(_adapter *adapter)
545
{
546
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
547
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
548
549
return mcfg->peer_sel_policy.cto_mgate_require
550
&& !rtw_bss_is_cto_mgate(&(mlmeext->mlmext_info.network));
551
}
552
553
u8 rtw_mesh_cto_mgate_network_filter(_adapter *adapter, struct wlan_network *scanned)
554
{
555
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
556
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
557
558
return !rtw_mesh_cto_mgate_required(adapter)
559
|| (rtw_bss_is_cto_mgate(&scanned->network)
560
&& !rtw_mesh_cto_mgate_blacklist_search(adapter, scanned->network.MacAddress));
561
}
562
563
int rtw_mesh_cto_mgate_blacklist_add(_adapter *adapter, const u8 *addr)
564
{
565
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
566
struct rtw_mesh_info *minfo = &adapter->mesh_info;
567
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
568
569
return rtw_blacklist_add(&plink_ctl->cto_mgate_blacklist, addr
570
, mcfg->peer_sel_policy.cto_mgate_blacklist_timeout_ms);
571
}
572
573
int rtw_mesh_cto_mgate_blacklist_del(_adapter *adapter, const u8 *addr)
574
{
575
struct rtw_mesh_info *minfo = &adapter->mesh_info;
576
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
577
578
return rtw_blacklist_del(&plink_ctl->cto_mgate_blacklist, addr);
579
}
580
581
int rtw_mesh_cto_mgate_blacklist_search(_adapter *adapter, const u8 *addr)
582
{
583
struct rtw_mesh_info *minfo = &adapter->mesh_info;
584
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
585
586
return rtw_blacklist_search(&plink_ctl->cto_mgate_blacklist, addr);
587
}
588
589
void rtw_mesh_cto_mgate_blacklist_flush(_adapter *adapter)
590
{
591
struct rtw_mesh_info *minfo = &adapter->mesh_info;
592
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
593
594
rtw_blacklist_flush(&plink_ctl->cto_mgate_blacklist);
595
}
596
597
void dump_mesh_cto_mgate_blacklist(void *sel, _adapter *adapter)
598
{
599
struct rtw_mesh_info *minfo = &adapter->mesh_info;
600
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
601
602
dump_blacklist(sel, &plink_ctl->cto_mgate_blacklist, "blacklist");
603
}
604
605
void dump_mesh_cto_mgate_blacklist_settings(void *sel, _adapter *adapter)
606
{
607
struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
608
609
RTW_PRINT_SEL(sel, "%-12s %-17s\n"
610
, "conf_timeout", "blacklist_timeout");
611
RTW_PRINT_SEL(sel, "%12u %17u\n"
612
, peer_sel_policy->cto_mgate_conf_timeout_ms
613
, peer_sel_policy->cto_mgate_blacklist_timeout_ms);
614
}
615
616
static void rtw_mesh_cto_mgate_blacklist_chk(_adapter *adapter)
617
{
618
struct rtw_mesh_info *minfo = &adapter->mesh_info;
619
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
620
_queue *blist = &plink_ctl->cto_mgate_blacklist;
621
_list *list, *head;
622
struct blacklist_ent *ent = NULL;
623
struct wlan_network *scanned = NULL;
624
625
enter_critical_bh(&blist->lock);
626
head = &blist->queue;
627
list = get_next(head);
628
while (rtw_end_of_queue_search(head, list) == _FALSE) {
629
ent = LIST_CONTAINOR(list, struct blacklist_ent, list);
630
list = get_next(list);
631
632
if (rtw_time_after(rtw_get_current_time(), ent->exp_time)) {
633
rtw_list_delete(&ent->list);
634
rtw_mfree(ent, sizeof(struct blacklist_ent));
635
continue;
636
}
637
638
scanned = rtw_find_network(&adapter->mlmepriv.scanned_queue, ent->addr);
639
if (!scanned)
640
continue;
641
642
if (rtw_bss_is_forwarding(&scanned->network)) {
643
rtw_list_delete(&ent->list);
644
rtw_mfree(ent, sizeof(struct blacklist_ent));
645
}
646
}
647
648
exit_critical_bh(&blist->lock);
649
}
650
#endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
651
652
void rtw_chk_candidate_peer_notify(_adapter *adapter, struct wlan_network *scanned)
653
{
654
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
655
struct mlme_priv *mlme = &adapter->mlmepriv;
656
struct rtw_mesh_info *minfo = &adapter->mesh_info;
657
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
658
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
659
bool acnode = 0;
660
661
if (IS_CH_WAITING(rfctl) && !IS_UNDER_CAC(rfctl))
662
goto exit;
663
664
if (plink_ctl->num >= RTW_MESH_MAX_PEER_CANDIDATES)
665
goto exit;
666
667
#if CONFIG_RTW_MESH_ACNODE_PREVENT
668
if (plink_ctl->acnode_rsvd) {
669
acnode = rtw_mesh_scanned_is_acnode_confirmed(adapter, scanned);
670
if (acnode && !rtw_mesh_scanned_is_acnode_allow_notify(adapter, scanned))
671
goto exit;
672
}
673
#endif
674
675
/* wpa_supplicant's auto peer will initiate peering when candidate peer is reported without max_peer_links consideration */
676
if (plink_ctl->num >= mcfg->max_peer_links + acnode ? 1 : 0)
677
goto exit;
678
679
if (rtw_get_passing_time_ms(scanned->last_scanned) >= mcfg->peer_sel_policy.scanr_exp_ms
680
|| (mcfg->rssi_threshold && mcfg->rssi_threshold > scanned->network.Rssi)
681
|| !rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
682
#if CONFIG_RTW_MACADDR_ACL
683
|| rtw_access_ctrl(adapter, scanned->network.MacAddress) == _FALSE
684
#endif
685
|| rtw_mesh_plink_get(adapter, scanned->network.MacAddress)
686
#if CONFIG_RTW_MESH_PEER_BLACKLIST
687
|| rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
688
#endif
689
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
690
|| !rtw_mesh_cto_mgate_network_filter(adapter, scanned)
691
#endif
692
)
693
goto exit;
694
695
#if CONFIG_RTW_MESH_ACNODE_PREVENT
696
if (acnode) {
697
scanned->acnode_notify_etime = 0;
698
RTW_INFO(FUNC_ADPT_FMT" acnode "MAC_FMT"\n"
699
, FUNC_ADPT_ARG(adapter), MAC_ARG(scanned->network.MacAddress));
700
}
701
#endif
702
703
#ifdef CONFIG_IOCTL_CFG80211
704
rtw_cfg80211_notify_new_peer_candidate(adapter->rtw_wdev
705
, scanned->network.MacAddress
706
, BSS_EX_TLV_IES(&scanned->network)
707
, BSS_EX_TLV_IES_LEN(&scanned->network)
708
, GFP_ATOMIC
709
);
710
#endif
711
712
exit:
713
return;
714
}
715
716
void rtw_mesh_peer_status_chk(_adapter *adapter)
717
{
718
struct mlme_priv *mlme = &adapter->mlmepriv;
719
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
720
struct rtw_mesh_info *minfo = &adapter->mesh_info;
721
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
722
struct mesh_plink_ent *plink;
723
_list *head, *list;
724
struct sta_info *sta = NULL;
725
struct sta_priv *stapriv = &adapter->stapriv;
726
int stainfo_offset;
727
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
728
u8 cto_mgate, forwarding, mgate;
729
#endif
730
u8 flush;
731
s8 flush_list[NUM_STA];
732
u8 flush_num = 0;
733
int i;
734
735
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
736
if (rtw_mesh_cto_mgate_required(adapter)) {
737
/* active scan on operating channel */
738
issue_probereq_ex(adapter, &adapter->mlmepriv.cur_network.network.mesh_id, NULL, 0, 0, 0, 0);
739
}
740
#endif
741
742
enter_critical_bh(&(plink_ctl->lock));
743
744
/* check established peers */
745
enter_critical_bh(&stapriv->asoc_list_lock);
746
747
head = &stapriv->asoc_list;
748
list = get_next(head);
749
while (rtw_end_of_queue_search(head, list) == _FALSE) {
750
sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
751
list = get_next(list);
752
753
if (!sta->plink || !sta->plink->scanned) {
754
rtw_warn_on(1);
755
continue;
756
}
757
plink = sta->plink;
758
flush = 0;
759
760
/* remove unsuitable peer */
761
if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 0)
762
#if CONFIG_RTW_MACADDR_ACL
763
|| rtw_access_ctrl(adapter, plink->addr) == _FALSE
764
#endif
765
) {
766
flush = 1;
767
goto flush_add;
768
}
769
770
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
771
cto_mgate = rtw_bss_is_cto_mgate(&(plink->scanned->network));
772
forwarding = rtw_bss_is_forwarding(&(plink->scanned->network));
773
mgate = rtw_mesh_gate_search(minfo->mesh_paths, sta->cmn.mac_addr);
774
775
/* CTO_MGATE required, remove peer without CTO_MGATE */
776
if (rtw_mesh_cto_mgate_required(adapter) && !cto_mgate) {
777
flush = 1;
778
goto flush_add;
779
}
780
781
/* cto_mgate_conf status update */
782
if (IS_CTO_MGATE_CONF_DISABLED(plink)) {
783
if (cto_mgate && !forwarding && !mgate)
784
SET_CTO_MGATE_CONF_END_TIME(plink, mcfg->peer_sel_policy.cto_mgate_conf_timeout_ms);
785
else
786
rtw_mesh_cto_mgate_blacklist_del(adapter, sta->cmn.mac_addr);
787
} else {
788
/* cto_mgate_conf ongoing */
789
if (cto_mgate && !forwarding && !mgate) {
790
if (IS_CTO_MGATE_CONF_TIMEOUT(plink)) {
791
rtw_mesh_cto_mgate_blacklist_add(adapter, sta->cmn.mac_addr);
792
793
/* CTO_MGATE required, remove peering can't achieve CTO_MGATE */
794
if (rtw_mesh_cto_mgate_required(adapter)) {
795
flush = 1;
796
goto flush_add;
797
}
798
}
799
} else {
800
SET_CTO_MGATE_CONF_DISABLED(plink);
801
rtw_mesh_cto_mgate_blacklist_del(adapter, sta->cmn.mac_addr);
802
}
803
}
804
#endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
805
806
flush_add:
807
if (flush) {
808
rtw_list_delete(&sta->asoc_list);
809
stapriv->asoc_list_cnt--;
810
STA_SET_MESH_PLINK(sta, NULL);
811
812
stainfo_offset = rtw_stainfo_offset(stapriv, sta);
813
if (stainfo_offset_valid(stainfo_offset))
814
flush_list[flush_num++] = stainfo_offset;
815
else
816
rtw_warn_on(1);
817
}
818
}
819
820
exit_critical_bh(&stapriv->asoc_list_lock);
821
822
/* check non-established peers */
823
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
824
plink = &plink_ctl->ent[i];
825
if (plink->valid != _TRUE || plink->plink_state == RTW_MESH_PLINK_ESTAB)
826
continue;
827
828
/* remove unsuitable peer */
829
if (!rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &plink->scanned->network, 1, 1)
830
#if CONFIG_RTW_MACADDR_ACL
831
|| rtw_access_ctrl(adapter, plink->addr) == _FALSE
832
#endif
833
) {
834
_rtw_mesh_expire_peer_ent(adapter, plink);
835
continue;
836
}
837
838
#if CONFIG_RTW_MESH_PEER_BLACKLIST
839
/* peer confirm check timeout, add to black list */
840
if (IS_PEER_CONF_TIMEOUT(plink)) {
841
rtw_mesh_peer_blacklist_add(adapter, plink->addr);
842
_rtw_mesh_expire_peer_ent(adapter, plink);
843
}
844
#endif
845
}
846
847
exit_critical_bh(&(plink_ctl->lock));
848
849
if (flush_num) {
850
u8 sta_addr[ETH_ALEN];
851
u8 updated = _FALSE;
852
853
for (i = 0; i < flush_num; i++) {
854
sta = rtw_get_stainfo_by_offset(stapriv, flush_list[i]);
855
_rtw_memcpy(sta_addr, sta->cmn.mac_addr, ETH_ALEN);
856
857
updated |= ap_free_sta(adapter, sta, _TRUE, WLAN_REASON_DEAUTH_LEAVING, _FALSE);
858
rtw_mesh_expire_peer(adapter, sta_addr);
859
}
860
861
associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
862
}
863
864
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
865
/* loop cto_mgate_blacklist to remove ent according to scan_r */
866
rtw_mesh_cto_mgate_blacklist_chk(adapter);
867
#endif
868
869
#if CONFIG_RTW_MESH_ACNODE_PREVENT
870
rtw_mesh_acnode_rsvd_chk(adapter);
871
#endif
872
873
return;
874
}
875
876
#if CONFIG_RTW_MESH_OFFCH_CAND
877
static u8 rtw_mesh_offch_cto_mgate_required(_adapter *adapter)
878
{
879
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
880
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
881
struct mlme_priv *mlme = &adapter->mlmepriv;
882
_queue *queue = &(mlme->scanned_queue);
883
_list *head, *pos;
884
struct wlan_network *scanned = NULL;
885
u8 ret = 0;
886
887
if (!rtw_mesh_cto_mgate_required(adapter))
888
goto exit;
889
890
enter_critical_bh(&(mlme->scanned_queue.lock));
891
892
head = get_list_head(queue);
893
pos = get_next(head);
894
while (!rtw_end_of_queue_search(head, pos)) {
895
scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
896
897
if (rtw_get_passing_time_ms(scanned->last_scanned) < mcfg->peer_sel_policy.scanr_exp_ms
898
&& (!mcfg->rssi_threshold || mcfg->rssi_threshold <= scanned->network.Rssi)
899
#if CONFIG_RTW_MACADDR_ACL
900
&& rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
901
#endif
902
&& rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 1, 1)
903
&& rtw_bss_is_cto_mgate(&scanned->network)
904
#if CONFIG_RTW_MESH_PEER_BLACKLIST
905
&& !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
906
#endif
907
&& !rtw_mesh_cto_mgate_blacklist_search(adapter, scanned->network.MacAddress)
908
)
909
break;
910
911
pos = get_next(pos);
912
}
913
914
if (rtw_end_of_queue_search(head, pos))
915
ret = 1;
916
917
exit_critical_bh(&(mlme->scanned_queue.lock));
918
919
exit:
920
return ret;
921
#else
922
return 0;
923
#endif /* CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST */
924
}
925
926
u8 rtw_mesh_offch_candidate_accepted(_adapter *adapter)
927
{
928
struct rtw_mesh_info *minfo = &adapter->mesh_info;
929
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
930
u8 ret = 0;
931
932
if (!adapter->mesh_cfg.peer_sel_policy.offch_cand)
933
goto exit;
934
935
ret = MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)
936
&& (!plink_ctl->num || rtw_mesh_offch_cto_mgate_required(adapter))
937
;
938
939
#ifdef CONFIG_CONCURRENT_MODE
940
if (ret) {
941
struct mi_state mstate_no_self;
942
943
rtw_mi_status_no_self(adapter, &mstate_no_self);
944
if (MSTATE_STA_LD_NUM(&mstate_no_self))
945
ret = 0;
946
}
947
#endif
948
949
exit:
950
return ret;
951
}
952
953
/*
954
* this function is called under off channel candidate is required
955
* the channel with maximum candidate count is selected
956
*/
957
u8 rtw_mesh_select_operating_ch(_adapter *adapter)
958
{
959
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
960
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
961
struct mlme_priv *mlme = &adapter->mlmepriv;
962
_queue *queue = &(mlme->scanned_queue);
963
_list *head, *pos;
964
_irqL irqL;
965
struct wlan_network *scanned = NULL;
966
int i;
967
/* statistics for candidate accept peering */
968
u8 cand_ap_cnt[MAX_CHANNEL_NUM] = {0};
969
u8 max_cand_ap_ch = 0;
970
u8 max_cand_ap_cnt = 0;
971
/* statistics for candidate including not accept peering */
972
u8 cand_cnt[MAX_CHANNEL_NUM] = {0};
973
u8 max_cand_ch = 0;
974
u8 max_cand_cnt = 0;
975
976
_enter_critical_bh(&(mlme->scanned_queue.lock), &irqL);
977
978
head = get_list_head(queue);
979
pos = get_next(head);
980
while (!rtw_end_of_queue_search(head, pos)) {
981
scanned = LIST_CONTAINOR(pos, struct wlan_network, list);
982
pos = get_next(pos);
983
984
if (rtw_get_passing_time_ms(scanned->last_scanned) < mcfg->peer_sel_policy.scanr_exp_ms
985
&& (!mcfg->rssi_threshold || mcfg->rssi_threshold <= scanned->network.Rssi)
986
#if CONFIG_RTW_MACADDR_ACL
987
&& rtw_access_ctrl(adapter, scanned->network.MacAddress) == _TRUE
988
#endif
989
&& rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &scanned->network, 0, 0)
990
#if CONFIG_RTW_MESH_PEER_BLACKLIST
991
&& !rtw_mesh_peer_blacklist_search(adapter, scanned->network.MacAddress)
992
#endif
993
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
994
&& rtw_mesh_cto_mgate_network_filter(adapter, scanned)
995
#endif
996
) {
997
int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, scanned->network.Configuration.DSConfig);
998
999
if (ch_set_idx >= 0
1000
&& !CH_IS_NON_OCP(&rfctl->channel_set[ch_set_idx])
1001
) {
1002
u8 nop, accept;
1003
1004
rtw_mesh_bss_peering_status(&scanned->network, &nop, &accept);
1005
cand_cnt[ch_set_idx]++;
1006
if (max_cand_cnt < cand_cnt[ch_set_idx]) {
1007
max_cand_cnt = cand_cnt[ch_set_idx];
1008
max_cand_ch = rfctl->channel_set[ch_set_idx].ChannelNum;
1009
}
1010
if (accept) {
1011
cand_ap_cnt[ch_set_idx]++;
1012
if (max_cand_ap_cnt < cand_ap_cnt[ch_set_idx]) {
1013
max_cand_ap_cnt = cand_ap_cnt[ch_set_idx];
1014
max_cand_ap_ch = rfctl->channel_set[ch_set_idx].ChannelNum;
1015
}
1016
}
1017
}
1018
}
1019
}
1020
1021
_exit_critical_bh(&(mlme->scanned_queue.lock), &irqL);
1022
1023
return max_cand_ap_ch ? max_cand_ap_ch : max_cand_ch;
1024
}
1025
1026
void dump_mesh_offch_cand_settings(void *sel, _adapter *adapter)
1027
{
1028
struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
1029
1030
RTW_PRINT_SEL(sel, "%-6s %-11s\n"
1031
, "enable", "find_int_ms");
1032
RTW_PRINT_SEL(sel, "%6u %11u\n"
1033
, peer_sel_policy->offch_cand, peer_sel_policy->offch_find_int_ms);
1034
}
1035
#endif /* CONFIG_RTW_MESH_OFFCH_CAND */
1036
1037
void dump_mesh_peer_sel_policy(void *sel, _adapter *adapter)
1038
{
1039
struct mesh_peer_sel_policy *peer_sel_policy = &adapter->mesh_cfg.peer_sel_policy;
1040
1041
RTW_PRINT_SEL(sel, "%-12s\n", "scanr_exp_ms");
1042
RTW_PRINT_SEL(sel, "%12u\n", peer_sel_policy->scanr_exp_ms);
1043
}
1044
1045
void dump_mesh_networks(void *sel, _adapter *adapter)
1046
{
1047
#if CONFIG_RTW_MESH_ACNODE_PREVENT
1048
#define NSTATE_TITLE_FMT_ACN " %-5s"
1049
#define NSTATE_VALUE_FMT_ACN " %5d"
1050
#define NSTATE_TITLE_ARG_ACN , "acn"
1051
#define NSTATE_VALUE_ARG_ACN , (acn_ms < 99999 ? acn_ms : 99999)
1052
#else
1053
#define NSTATE_TITLE_FMT_ACN ""
1054
#define NSTATE_VALUE_FMT_ACN ""
1055
#define NSTATE_TITLE_ARG_ACN
1056
#define NSTATE_VALUE_ARG_ACN
1057
#endif
1058
1059
struct mlme_priv *mlme = &(adapter->mlmepriv);
1060
_queue *queue = &(mlme->scanned_queue);
1061
struct wlan_network *network;
1062
_list *list, *head;
1063
u8 same_mbss;
1064
u8 candidate;
1065
struct mesh_plink_ent *plink;
1066
u8 blocked;
1067
u8 established;
1068
s32 age_ms;
1069
#if CONFIG_RTW_MESH_ACNODE_PREVENT
1070
s32 acn_ms;
1071
#endif
1072
u8 *mesh_conf_ie;
1073
sint mesh_conf_ie_len;
1074
struct wlan_network **mesh_networks;
1075
u8 mesh_network_cnt = 0;
1076
int i;
1077
1078
mesh_networks = rtw_zvmalloc(mlme->max_bss_cnt * sizeof(struct wlan_network *));
1079
if (!mesh_networks)
1080
return;
1081
1082
enter_critical_bh(&queue->lock);
1083
head = get_list_head(queue);
1084
list = get_next(head);
1085
1086
while (rtw_end_of_queue_search(head, list) == _FALSE) {
1087
network = LIST_CONTAINOR(list, struct wlan_network, list);
1088
list = get_next(list);
1089
1090
if (network->network.InfrastructureMode != Ndis802_11_mesh)
1091
continue;
1092
1093
mesh_conf_ie = rtw_get_ie(BSS_EX_TLV_IES(&network->network), WLAN_EID_MESH_CONFIG
1094
, &mesh_conf_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
1095
if (!mesh_conf_ie || mesh_conf_ie_len != 7)
1096
continue;
1097
1098
mesh_networks[mesh_network_cnt++] = network;
1099
}
1100
1101
exit_critical_bh(&queue->lock);
1102
1103
RTW_PRINT_SEL(sel, " %-17s %-3s %-4s %-5s %-32s %-3s %-3s %-3s"
1104
NSTATE_TITLE_FMT_ACN
1105
"\n"
1106
, "bssid", "ch", "rssi", "age", "mesh_id", "nop", "fwd", "cto"
1107
NSTATE_TITLE_ARG_ACN
1108
);
1109
1110
for (i = 0; i < mesh_network_cnt; i++) {
1111
network = mesh_networks[i];
1112
1113
if (network->network.InfrastructureMode != Ndis802_11_mesh)
1114
continue;
1115
1116
mesh_conf_ie = rtw_get_ie(BSS_EX_TLV_IES(&network->network), WLAN_EID_MESH_CONFIG
1117
, &mesh_conf_ie_len, BSS_EX_TLV_IES_LEN(&network->network));
1118
if (!mesh_conf_ie || mesh_conf_ie_len != 7)
1119
continue;
1120
1121
age_ms = rtw_get_passing_time_ms(network->last_scanned);
1122
#if CONFIG_RTW_MESH_ACNODE_PREVENT
1123
if (network->acnode_stime == 0)
1124
acn_ms = 0;
1125
else
1126
acn_ms = rtw_get_passing_time_ms(network->acnode_stime);
1127
#endif
1128
same_mbss = 0;
1129
candidate = 0;
1130
plink = NULL;
1131
blocked = 0;
1132
established = 0;
1133
1134
if (MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)) {
1135
plink = rtw_mesh_plink_get(adapter, network->network.MacAddress);
1136
if (plink && plink->plink_state == RTW_MESH_PLINK_ESTAB)
1137
established = 1;
1138
else if (plink && plink->plink_state == RTW_MESH_PLINK_BLOCKED)
1139
blocked = 1;
1140
else if (plink)
1141
;
1142
else if (rtw_bss_is_candidate_mesh_peer(&mlme->cur_network.network, &network->network, 0, 1))
1143
candidate = 1;
1144
else if (rtw_bss_is_same_mbss(&mlme->cur_network.network, &network->network))
1145
same_mbss = 1;
1146
}
1147
1148
RTW_PRINT_SEL(sel, "%c "MAC_FMT" %3d %4ld %5d %-32s %c%2u %3u %c%c "
1149
NSTATE_VALUE_FMT_ACN
1150
"\n"
1151
, established ? 'E' : (blocked ? 'B' : (plink ? 'N' : (candidate ? 'C' : (same_mbss ? 'S' : ' '))))
1152
, MAC_ARG(network->network.MacAddress)
1153
, network->network.Configuration.DSConfig
1154
, network->network.Rssi
1155
, age_ms < 99999 ? age_ms : 99999
1156
, network->network.mesh_id.Ssid
1157
, GET_MESH_CONF_ELE_ACCEPT_PEERINGS(mesh_conf_ie + 2) ? '+' : ' '
1158
, GET_MESH_CONF_ELE_NUM_OF_PEERINGS(mesh_conf_ie + 2)
1159
, GET_MESH_CONF_ELE_FORWARDING(mesh_conf_ie + 2)
1160
, GET_MESH_CONF_ELE_CTO_MGATE(mesh_conf_ie + 2) ? 'G' : ' '
1161
, GET_MESH_CONF_ELE_CTO_AS(mesh_conf_ie + 2) ? 'A' : ' '
1162
NSTATE_VALUE_ARG_ACN
1163
);
1164
}
1165
1166
rtw_vmfree(mesh_networks, mlme->max_bss_cnt * sizeof(struct wlan_network *));
1167
}
1168
1169
void rtw_mesh_adjust_chbw(u8 req_ch, u8 *req_bw, u8 *req_offset)
1170
{
1171
if (req_ch >= 5 && req_ch <= 9) {
1172
/* prevent secondary channel offset mismatch */
1173
if (*req_bw > CHANNEL_WIDTH_20) {
1174
*req_bw = CHANNEL_WIDTH_20;
1175
*req_offset = HAL_PRIME_CHNL_OFFSET_DONT_CARE;
1176
}
1177
}
1178
}
1179
1180
void rtw_mesh_sae_check_frames(_adapter *adapter, const u8 *buf, u32 len, u8 tx, u16 alg, u16 seq, u16 status)
1181
{
1182
#if CONFIG_RTW_MESH_PEER_BLACKLIST
1183
if (tx && seq == 1)
1184
rtw_mesh_plink_set_peer_conf_timeout(adapter, GetAddr1Ptr(buf));
1185
#endif
1186
}
1187
1188
#if CONFIG_RTW_MPM_TX_IES_SYNC_BSS
1189
#ifdef CONFIG_RTW_MESH_AEK
1190
static int rtw_mpm_ampe_dec(_adapter *adapter, struct mesh_plink_ent *plink
1191
, u8 *fhead, size_t flen, u8* fbody, u8 *mic_ie, u8 *ampe_buf)
1192
{
1193
int ret = _FAIL, verify_ret;
1194
const u8 *aad[] = {adapter_mac_addr(adapter), plink->addr, fbody};
1195
const size_t aad_len[] = {ETH_ALEN, ETH_ALEN, mic_ie - fbody};
1196
u8 *iv_crypt;
1197
size_t iv_crypt_len = flen - (mic_ie + 2 - fhead);
1198
1199
iv_crypt = rtw_malloc(iv_crypt_len);
1200
if (!iv_crypt)
1201
goto exit;
1202
1203
_rtw_memcpy(iv_crypt, mic_ie + 2, iv_crypt_len);
1204
1205
verify_ret = aes_siv_decrypt(plink->aek, iv_crypt, iv_crypt_len
1206
, 3, aad, aad_len, ampe_buf);
1207
1208
rtw_mfree(iv_crypt, iv_crypt_len);
1209
1210
if (verify_ret) {
1211
RTW_WARN("verify error, aek_valid=%u\n", plink->aek_valid);
1212
goto exit;
1213
} else if (*ampe_buf != WLAN_EID_AMPE) {
1214
RTW_WARN("plaintext is not AMPE IE\n");
1215
goto exit;
1216
} else if (AES_BLOCK_SIZE + 2 + *(ampe_buf + 1) > iv_crypt_len) {
1217
RTW_WARN("plaintext AMPE IE length is not valid\n");
1218
goto exit;
1219
}
1220
1221
ret = _SUCCESS;
1222
1223
exit:
1224
return ret;
1225
}
1226
1227
static int rtw_mpm_ampe_enc(_adapter *adapter, struct mesh_plink_ent *plink
1228
, u8* fbody, u8 *mic_ie, u8 *ampe_buf, bool inverse)
1229
{
1230
int ret = _FAIL, protect_ret;
1231
const u8 *aad[3];
1232
const size_t aad_len[3] = {ETH_ALEN, ETH_ALEN, mic_ie - fbody};
1233
u8 *ampe_ie;
1234
size_t ampe_ie_len = *(ampe_buf + 1) + 2; /* including id & len */
1235
1236
if (inverse) {
1237
aad[0] = plink->addr;
1238
aad[1] = adapter_mac_addr(adapter);
1239
} else {
1240
aad[0] = adapter_mac_addr(adapter);
1241
aad[1] = plink->addr;
1242
}
1243
aad[2] = fbody;
1244
1245
ampe_ie = rtw_malloc(ampe_ie_len);
1246
if (!ampe_ie)
1247
goto exit;
1248
1249
_rtw_memcpy(ampe_ie, ampe_buf, ampe_ie_len);
1250
1251
protect_ret = aes_siv_encrypt(plink->aek, ampe_ie, ampe_ie_len
1252
, 3, aad, aad_len, mic_ie + 2);
1253
1254
rtw_mfree(ampe_ie, ampe_ie_len);
1255
1256
if (protect_ret) {
1257
RTW_WARN("protect error, aek_valid=%u\n", plink->aek_valid);
1258
goto exit;
1259
}
1260
1261
ret = _SUCCESS;
1262
1263
exit:
1264
return ret;
1265
}
1266
#endif /* CONFIG_RTW_MESH_AEK */
1267
1268
static int rtw_mpm_tx_ies_sync_bss(_adapter *adapter, struct mesh_plink_ent *plink
1269
, u8 *fhead, size_t flen, u8* fbody, u8 tlv_ies_offset, u8 *mpm_ie, u8 *mic_ie
1270
, u8 **nbuf, size_t *nlen)
1271
{
1272
int ret = _FAIL;
1273
struct mlme_priv *mlme = &(adapter->mlmepriv);
1274
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
1275
struct mlme_ext_info *mlmeinfo = &(mlmeext->mlmext_info);
1276
WLAN_BSSID_EX *network = &(mlmeinfo->network);
1277
uint left;
1278
u8 *pos;
1279
1280
uint mpm_ielen = *(mpm_ie + 1);
1281
u8 *fpos;
1282
u8 *new_buf = NULL;
1283
size_t new_len = 0;
1284
1285
u8 *new_fhead;
1286
size_t new_flen;
1287
u8 *new_fbody;
1288
u8 *new_mic_ie;
1289
1290
#ifdef CONFIG_RTW_MESH_AEK
1291
u8 *ampe_buf = NULL;
1292
size_t ampe_buf_len = 0;
1293
1294
/* decode */
1295
if (mic_ie) {
1296
ampe_buf_len = flen - (mic_ie + 2 + AES_BLOCK_SIZE - fhead);
1297
ampe_buf = rtw_malloc(ampe_buf_len);
1298
if (!ampe_buf)
1299
goto exit;
1300
1301
if (rtw_mpm_ampe_dec(adapter, plink, fhead, flen, fbody, mic_ie, ampe_buf) != _SUCCESS)
1302
goto exit;
1303
1304
if (*(ampe_buf + 1) >= 68) {
1305
_rtw_memcpy(plink->sel_pcs, ampe_buf + 2, 4);
1306
_rtw_memcpy(plink->l_nonce, ampe_buf + 6, 32);
1307
_rtw_memcpy(plink->p_nonce, ampe_buf + 38, 32);
1308
}
1309
}
1310
#endif
1311
1312
/* count for new frame length */
1313
new_len = sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset;
1314
left = BSS_EX_TLV_IES_LEN(network);
1315
pos = BSS_EX_TLV_IES(network);
1316
while (left >= 2) {
1317
u8 id, elen;
1318
1319
id = *pos++;
1320
elen = *pos++;
1321
left -= 2;
1322
1323
if (elen > left)
1324
break;
1325
1326
switch (id) {
1327
case WLAN_EID_SSID:
1328
case WLAN_EID_DS_PARAMS:
1329
case WLAN_EID_TIM:
1330
break;
1331
default:
1332
new_len += 2 + elen;
1333
}
1334
1335
left -= elen;
1336
pos += elen;
1337
}
1338
new_len += mpm_ielen + 2;
1339
if (mic_ie)
1340
new_len += AES_BLOCK_SIZE + 2 + ampe_buf_len;
1341
1342
/* alloc new frame */
1343
new_buf = rtw_malloc(new_len);
1344
if (!new_buf) {
1345
rtw_warn_on(1);
1346
goto exit;
1347
}
1348
1349
/* build new frame */
1350
_rtw_memcpy(new_buf, fhead, sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset);
1351
new_fhead = new_buf;
1352
new_flen = new_len;
1353
new_fbody = new_fhead + sizeof(struct rtw_ieee80211_hdr_3addr);
1354
1355
fpos = new_fbody + tlv_ies_offset;
1356
left = BSS_EX_TLV_IES_LEN(network);
1357
pos = BSS_EX_TLV_IES(network);
1358
while (left >= 2) {
1359
u8 id, elen;
1360
1361
id = *pos++;
1362
elen = *pos++;
1363
left -= 2;
1364
1365
if (elen > left)
1366
break;
1367
1368
switch (id) {
1369
case WLAN_EID_SSID:
1370
case WLAN_EID_DS_PARAMS:
1371
case WLAN_EID_TIM:
1372
break;
1373
default:
1374
fpos = rtw_set_ie(fpos, id, elen, pos, NULL);
1375
if (id == WLAN_EID_MESH_CONFIG)
1376
fpos = rtw_set_ie(fpos, WLAN_EID_MPM, mpm_ielen, mpm_ie + 2, NULL);
1377
}
1378
1379
left -= elen;
1380
pos += elen;
1381
}
1382
if (mic_ie) {
1383
new_mic_ie = fpos;
1384
*fpos++ = WLAN_EID_MIC;
1385
*fpos++ = AES_BLOCK_SIZE;
1386
}
1387
1388
#ifdef CONFIG_RTW_MESH_AEK
1389
/* encode */
1390
if (mic_ie) {
1391
int enc_ret = rtw_mpm_ampe_enc(adapter, plink, new_fbody, new_mic_ie, ampe_buf, 0);
1392
if (enc_ret != _SUCCESS)
1393
goto exit;
1394
}
1395
#endif
1396
1397
*nlen = new_len;
1398
*nbuf = new_buf;
1399
1400
ret = _SUCCESS;
1401
1402
exit:
1403
if (ret != _SUCCESS && new_buf)
1404
rtw_mfree(new_buf, new_len);
1405
1406
#ifdef CONFIG_RTW_MESH_AEK
1407
if (ampe_buf)
1408
rtw_mfree(ampe_buf, ampe_buf_len);
1409
#endif
1410
1411
return ret;
1412
}
1413
#endif /* CONFIG_RTW_MPM_TX_IES_SYNC_BSS */
1414
1415
struct mpm_frame_info {
1416
u8 *aid;
1417
u16 aid_v;
1418
u8 *pid;
1419
u16 pid_v;
1420
u8 *llid;
1421
u16 llid_v;
1422
u8 *plid;
1423
u16 plid_v;
1424
u8 *reason;
1425
u16 reason_v;
1426
u8 *chosen_pmk;
1427
};
1428
1429
/*
1430
* pid:00000 llid:00000 chosen_pmk:0x00000000000000000000000000000000
1431
* aid:00000 pid:00000 llid:00000 plid:00000 chosen_pmk:0x00000000000000000000000000000000
1432
* pid:00000 llid:00000 plid:00000 reason:00000 chosen_pmk:0x00000000000000000000000000000000
1433
*/
1434
#define MPM_LOG_BUF_LEN 92 /* this length is limited for legal combination */
1435
static void rtw_mpm_info_msg(struct mpm_frame_info *mpm_info, u8 *mpm_log_buf)
1436
{
1437
int cnt = 0;
1438
1439
if (mpm_info->aid) {
1440
cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "aid:%u ", mpm_info->aid_v);
1441
if (cnt >= MPM_LOG_BUF_LEN - 1)
1442
goto exit;
1443
}
1444
if (mpm_info->pid) {
1445
cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "pid:%u ", mpm_info->pid_v);
1446
if (cnt >= MPM_LOG_BUF_LEN - 1)
1447
goto exit;
1448
}
1449
if (mpm_info->llid) {
1450
cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "llid:%u ", mpm_info->llid_v);
1451
if (cnt >= MPM_LOG_BUF_LEN - 1)
1452
goto exit;
1453
}
1454
if (mpm_info->plid) {
1455
cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "plid:%u ", mpm_info->plid_v);
1456
if (cnt >= MPM_LOG_BUF_LEN - 1)
1457
goto exit;
1458
}
1459
if (mpm_info->reason) {
1460
cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "reason:%u ", mpm_info->reason_v);
1461
if (cnt >= MPM_LOG_BUF_LEN - 1)
1462
goto exit;
1463
}
1464
if (mpm_info->chosen_pmk) {
1465
cnt += snprintf(mpm_log_buf + cnt, MPM_LOG_BUF_LEN - cnt - 1, "chosen_pmk:0x"KEY_FMT, KEY_ARG(mpm_info->chosen_pmk));
1466
if (cnt >= MPM_LOG_BUF_LEN - 1)
1467
goto exit;
1468
}
1469
1470
exit:
1471
return;
1472
}
1473
1474
static int rtw_mpm_check_frames(_adapter *adapter, u8 action, const u8 **buf, size_t *len, u8 tx)
1475
{
1476
struct rtw_mesh_info *minfo = &adapter->mesh_info;
1477
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
1478
struct mesh_plink_ent *plink = NULL;
1479
u8 *nbuf = NULL;
1480
size_t nlen = 0;
1481
u8 *fhead = (u8 *)*buf;
1482
size_t flen = *len;
1483
u8 *peer_addr = tx ? GetAddr1Ptr(fhead) : get_addr2_ptr(fhead);
1484
u8 *frame_body = fhead + sizeof(struct rtw_ieee80211_hdr_3addr);
1485
struct mpm_frame_info mpm_info;
1486
u8 tlv_ies_offset;
1487
u8 *mpm_ie = NULL;
1488
uint mpm_ielen = 0;
1489
u8 *mic_ie = NULL;
1490
uint mic_ielen = 0;
1491
int ret = 0;
1492
u8 mpm_log_buf[MPM_LOG_BUF_LEN] = {0};
1493
1494
if (action == RTW_ACT_SELF_PROTECTED_MESH_OPEN)
1495
tlv_ies_offset = 4;
1496
else if (action == RTW_ACT_SELF_PROTECTED_MESH_CONF)
1497
tlv_ies_offset = 6;
1498
else if (action == RTW_ACT_SELF_PROTECTED_MESH_CLOSE)
1499
tlv_ies_offset = 2;
1500
else {
1501
rtw_warn_on(1);
1502
goto exit;
1503
}
1504
1505
plink = rtw_mesh_plink_get(adapter, peer_addr);
1506
if (!plink && (tx == _TRUE || action == RTW_ACT_SELF_PROTECTED_MESH_CONF)) {
1507
/* warning message if no plink when: 1.TX all MPM or 2.RX CONF */
1508
RTW_WARN("RTW_%s:%s without plink of "MAC_FMT"\n"
1509
, (tx == _TRUE) ? "Tx" : "Rx", action_self_protected_str(action), MAC_ARG(peer_addr));
1510
goto exit;
1511
}
1512
1513
_rtw_memset(&mpm_info, 0, sizeof(struct mpm_frame_info));
1514
1515
if (action == RTW_ACT_SELF_PROTECTED_MESH_CONF) {
1516
mpm_info.aid = (u8 *)frame_body + 4;
1517
mpm_info.aid_v = RTW_GET_LE16(mpm_info.aid);
1518
}
1519
1520
mpm_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
1521
, WLAN_EID_MPM, &mpm_ielen
1522
, flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
1523
if (!mpm_ie || mpm_ielen < 2 + 2)
1524
goto exit;
1525
1526
mpm_info.pid = mpm_ie + 2;
1527
mpm_info.pid_v = RTW_GET_LE16(mpm_info.pid);
1528
mpm_info.llid = mpm_info.pid + 2;
1529
mpm_info.llid_v = RTW_GET_LE16(mpm_info.llid);
1530
1531
switch (action) {
1532
case RTW_ACT_SELF_PROTECTED_MESH_OPEN:
1533
/* pid:2, llid:2, (chosen_pmk:16) */
1534
if (mpm_info.pid_v == 0 && mpm_ielen == 4)
1535
;
1536
else if (mpm_info.pid_v == 1 && mpm_ielen == 20)
1537
mpm_info.chosen_pmk = mpm_info.llid + 2;
1538
else
1539
goto exit;
1540
break;
1541
case RTW_ACT_SELF_PROTECTED_MESH_CONF:
1542
/* pid:2, llid:2, plid:2, (chosen_pmk:16) */
1543
mpm_info.plid = mpm_info.llid + 2;
1544
mpm_info.plid_v = RTW_GET_LE16(mpm_info.plid);
1545
if (mpm_info.pid_v == 0 && mpm_ielen == 6)
1546
;
1547
else if (mpm_info.pid_v == 1 && mpm_ielen == 22)
1548
mpm_info.chosen_pmk = mpm_info.plid + 2;
1549
else
1550
goto exit;
1551
break;
1552
case RTW_ACT_SELF_PROTECTED_MESH_CLOSE:
1553
/* pid:2, llid:2, (plid:2), reason:2, (chosen_pmk:16) */
1554
if (mpm_info.pid_v == 0 && mpm_ielen == 6) {
1555
/* MPM, without plid */
1556
mpm_info.reason = mpm_info.llid + 2;
1557
mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
1558
} else if (mpm_info.pid_v == 0 && mpm_ielen == 8) {
1559
/* MPM, with plid */
1560
mpm_info.plid = mpm_info.llid + 2;
1561
mpm_info.plid_v = RTW_GET_LE16(mpm_info.plid);
1562
mpm_info.reason = mpm_info.plid + 2;
1563
mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
1564
} else if (mpm_info.pid_v == 1 && mpm_ielen == 22) {
1565
/* AMPE, without plid */
1566
mpm_info.reason = mpm_info.llid + 2;
1567
mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
1568
mpm_info.chosen_pmk = mpm_info.reason + 2;
1569
} else if (mpm_info.pid_v == 1 && mpm_ielen == 24) {
1570
/* AMPE, with plid */
1571
mpm_info.plid = mpm_info.llid + 2;
1572
mpm_info.plid_v = RTW_GET_LE16(mpm_info.plid);
1573
mpm_info.reason = mpm_info.plid + 2;
1574
mpm_info.reason_v = RTW_GET_LE16(mpm_info.reason);
1575
mpm_info.chosen_pmk = mpm_info.reason + 2;
1576
} else
1577
goto exit;
1578
break;
1579
};
1580
1581
if (mpm_info.pid_v == 1) {
1582
mic_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
1583
, WLAN_EID_MIC, &mic_ielen
1584
, flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
1585
if (!mic_ie || mic_ielen != AES_BLOCK_SIZE)
1586
goto exit;
1587
}
1588
1589
#if CONFIG_RTW_MPM_TX_IES_SYNC_BSS
1590
if ((action == RTW_ACT_SELF_PROTECTED_MESH_OPEN || action == RTW_ACT_SELF_PROTECTED_MESH_CONF)
1591
&& tx == _TRUE
1592
) {
1593
#define DBG_RTW_MPM_TX_IES_SYNC_BSS 0
1594
1595
if (mpm_info.pid_v == 1 && (!plink || !MESH_PLINK_AEK_VALID(plink))) {
1596
RTW_WARN("AEK not ready, IEs can't sync with BSS\n");
1597
goto bypass_sync_bss;
1598
}
1599
1600
if (DBG_RTW_MPM_TX_IES_SYNC_BSS) {
1601
RTW_INFO(FUNC_ADPT_FMT" before:\n", FUNC_ADPT_ARG(adapter));
1602
dump_ies(RTW_DBGDUMP
1603
, fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
1604
, flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
1605
}
1606
1607
rtw_mpm_tx_ies_sync_bss(adapter, plink
1608
, fhead, flen, frame_body, tlv_ies_offset, mpm_ie, mic_ie
1609
, &nbuf, &nlen);
1610
if (!nbuf)
1611
goto exit;
1612
1613
/* update pointer & len for new frame */
1614
fhead = nbuf;
1615
flen = nlen;
1616
frame_body = fhead + sizeof(struct rtw_ieee80211_hdr_3addr);
1617
if (mpm_info.pid_v == 1) {
1618
mic_ie = rtw_get_ie(fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
1619
, WLAN_EID_MIC, &mic_ielen
1620
, flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
1621
}
1622
1623
if (DBG_RTW_MPM_TX_IES_SYNC_BSS) {
1624
RTW_INFO(FUNC_ADPT_FMT" after:\n", FUNC_ADPT_ARG(adapter));
1625
dump_ies(RTW_DBGDUMP
1626
, fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + tlv_ies_offset
1627
, flen - sizeof(struct rtw_ieee80211_hdr_3addr) - tlv_ies_offset);
1628
}
1629
}
1630
bypass_sync_bss:
1631
#endif /* CONFIG_RTW_MPM_TX_IES_SYNC_BSS */
1632
1633
if (!plink)
1634
goto mpm_log;
1635
1636
#if CONFIG_RTW_MESH_PEER_BLACKLIST
1637
if (action == RTW_ACT_SELF_PROTECTED_MESH_OPEN) {
1638
if (tx)
1639
rtw_mesh_plink_set_peer_conf_timeout(adapter, peer_addr);
1640
1641
} else
1642
#endif
1643
#if CONFIG_RTW_MESH_ACNODE_PREVENT
1644
if (action == RTW_ACT_SELF_PROTECTED_MESH_CLOSE) {
1645
if (tx && mpm_info.reason && mpm_info.reason_v == WLAN_REASON_MESH_MAX_PEERS) {
1646
if (rtw_mesh_scanned_is_acnode_confirmed(adapter, plink->scanned)
1647
&& rtw_mesh_acnode_prevent_allow_sacrifice(adapter)
1648
) {
1649
struct sta_info *sac = rtw_mesh_acnode_prevent_pick_sacrifice(adapter);
1650
1651
if (sac) {
1652
struct sta_priv *stapriv = &adapter->stapriv;
1653
_irqL irqL;
1654
u8 sta_addr[ETH_ALEN];
1655
u8 updated = _FALSE;
1656
1657
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
1658
if (!rtw_is_list_empty(&sac->asoc_list)) {
1659
rtw_list_delete(&sac->asoc_list);
1660
stapriv->asoc_list_cnt--;
1661
STA_SET_MESH_PLINK(sac, NULL);
1662
}
1663
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
1664
RTW_INFO(FUNC_ADPT_FMT" sacrifice "MAC_FMT" for acnode\n"
1665
, FUNC_ADPT_ARG(adapter), MAC_ARG(sac->cmn.mac_addr));
1666
1667
_rtw_memcpy(sta_addr, sac->cmn.mac_addr, ETH_ALEN);
1668
updated = ap_free_sta(adapter, sac, 0, 0, 1);
1669
rtw_mesh_expire_peer(stapriv->padapter, sta_addr);
1670
1671
associated_clients_update(adapter, updated, STA_INFO_UPDATE_ALL);
1672
}
1673
}
1674
}
1675
} else
1676
#endif
1677
if (action == RTW_ACT_SELF_PROTECTED_MESH_CONF) {
1678
_irqL irqL;
1679
u8 *ies = NULL;
1680
u16 ies_len = 0;
1681
1682
_enter_critical_bh(&(plink_ctl->lock), &irqL);
1683
1684
plink = _rtw_mesh_plink_get(adapter, peer_addr);
1685
if (!plink)
1686
goto release_plink_ctl;
1687
1688
if (tx == _FALSE) {
1689
ies = plink->rx_conf_ies;
1690
ies_len = plink->rx_conf_ies_len;
1691
plink->rx_conf_ies = NULL;
1692
plink->rx_conf_ies_len = 0;
1693
1694
plink->llid = mpm_info.plid_v;
1695
plink->plid = mpm_info.llid_v;
1696
plink->peer_aid = mpm_info.aid_v;
1697
if (mpm_info.pid_v == 1)
1698
_rtw_memcpy(plink->chosen_pmk, mpm_info.chosen_pmk, 16);
1699
}
1700
#ifdef CONFIG_RTW_MESH_DRIVER_AID
1701
else {
1702
ies = plink->tx_conf_ies;
1703
ies_len = plink->tx_conf_ies_len;
1704
plink->tx_conf_ies = NULL;
1705
plink->tx_conf_ies_len = 0;
1706
}
1707
#endif
1708
1709
if (ies && ies_len)
1710
rtw_mfree(ies, ies_len);
1711
1712
#ifndef CONFIG_RTW_MESH_DRIVER_AID
1713
if (tx == _TRUE)
1714
goto release_plink_ctl; /* no need to copy tx conf ies */
1715
#endif
1716
1717
/* copy mesh confirm IEs */
1718
if (mpm_info.pid_v == 1) /* not include MIC & encrypted AMPE */
1719
ies_len = (mic_ie - fhead) - sizeof(struct rtw_ieee80211_hdr_3addr) - 2;
1720
else
1721
ies_len = flen - sizeof(struct rtw_ieee80211_hdr_3addr) - 2;
1722
1723
ies = rtw_zmalloc(ies_len);
1724
if (ies) {
1725
_rtw_memcpy(ies, fhead + sizeof(struct rtw_ieee80211_hdr_3addr) + 2, ies_len);
1726
if (tx == _FALSE) {
1727
plink->rx_conf_ies = ies;
1728
plink->rx_conf_ies_len = ies_len;
1729
}
1730
#ifdef CONFIG_RTW_MESH_DRIVER_AID
1731
else {
1732
plink->tx_conf_ies = ies;
1733
plink->tx_conf_ies_len = ies_len;
1734
}
1735
#endif
1736
}
1737
1738
release_plink_ctl:
1739
_exit_critical_bh(&(plink_ctl->lock), &irqL);
1740
}
1741
1742
mpm_log:
1743
rtw_mpm_info_msg(&mpm_info, mpm_log_buf);
1744
RTW_INFO("RTW_%s:%s %s\n"
1745
, (tx == _TRUE) ? "Tx" : "Rx"
1746
, action_self_protected_str(action)
1747
, mpm_log_buf
1748
);
1749
1750
ret = 1;
1751
1752
exit:
1753
if (nbuf) {
1754
if (ret == 1) {
1755
*buf = nbuf;
1756
*len = nlen;
1757
} else
1758
rtw_mfree(nbuf, nlen);
1759
}
1760
1761
return ret;
1762
}
1763
1764
static int rtw_mesh_check_frames(_adapter *adapter, const u8 **buf, size_t *len, u8 tx)
1765
{
1766
int is_mesh_frame = -1;
1767
const u8 *frame_body;
1768
u8 category, action;
1769
1770
frame_body = *buf + sizeof(struct rtw_ieee80211_hdr_3addr);
1771
category = frame_body[0];
1772
1773
if (category == RTW_WLAN_CATEGORY_SELF_PROTECTED) {
1774
action = frame_body[1];
1775
switch (action) {
1776
case RTW_ACT_SELF_PROTECTED_MESH_OPEN:
1777
case RTW_ACT_SELF_PROTECTED_MESH_CONF:
1778
case RTW_ACT_SELF_PROTECTED_MESH_CLOSE:
1779
rtw_mpm_check_frames(adapter, action, buf, len, tx);
1780
is_mesh_frame = action;
1781
break;
1782
case RTW_ACT_SELF_PROTECTED_MESH_GK_INFORM:
1783
case RTW_ACT_SELF_PROTECTED_MESH_GK_ACK:
1784
RTW_INFO("RTW_%s:%s\n", (tx == _TRUE) ? "Tx" : "Rx", action_self_protected_str(action));
1785
is_mesh_frame = action;
1786
break;
1787
default:
1788
break;
1789
};
1790
}
1791
1792
return is_mesh_frame;
1793
}
1794
1795
int rtw_mesh_check_frames_tx(_adapter *adapter, const u8 **buf, size_t *len)
1796
{
1797
return rtw_mesh_check_frames(adapter, buf, len, _TRUE);
1798
}
1799
1800
int rtw_mesh_check_frames_rx(_adapter *adapter, const u8 *buf, size_t len)
1801
{
1802
return rtw_mesh_check_frames(adapter, &buf, &len, _FALSE);
1803
}
1804
1805
int rtw_mesh_on_auth(_adapter *adapter, union recv_frame *rframe)
1806
{
1807
u8 *whdr = rframe->u.hdr.rx_data;
1808
1809
#if CONFIG_RTW_MACADDR_ACL
1810
if (rtw_access_ctrl(adapter, get_addr2_ptr(whdr)) == _FALSE)
1811
return _SUCCESS;
1812
#endif
1813
1814
if (!rtw_mesh_plink_get(adapter, get_addr2_ptr(whdr))) {
1815
#if CONFIG_RTW_MESH_ACNODE_PREVENT
1816
rtw_mesh_acnode_set_notify_etime(adapter, whdr);
1817
#endif
1818
1819
if (adapter_to_rfctl(adapter)->offch_state == OFFCHS_NONE)
1820
issue_probereq(adapter, &adapter->mlmepriv.cur_network.network.mesh_id, get_addr2_ptr(whdr));
1821
1822
/* only peer being added (checked by notify conditions) is allowed */
1823
return _SUCCESS;
1824
}
1825
1826
rtw_cfg80211_rx_mframe(adapter, rframe, NULL);
1827
return _SUCCESS;
1828
}
1829
1830
unsigned int on_action_self_protected(_adapter *adapter, union recv_frame *rframe)
1831
{
1832
unsigned int ret = _FAIL;
1833
struct sta_info *sta = NULL;
1834
u8 *pframe = rframe->u.hdr.rx_data;
1835
uint frame_len = rframe->u.hdr.len;
1836
u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
1837
u8 category;
1838
u8 action;
1839
1840
/* check RA matches or not */
1841
if (!_rtw_memcmp(adapter_mac_addr(adapter), GetAddr1Ptr(pframe), ETH_ALEN))
1842
goto exit;
1843
1844
category = frame_body[0];
1845
if (category != RTW_WLAN_CATEGORY_SELF_PROTECTED)
1846
goto exit;
1847
1848
action = frame_body[1];
1849
switch (action) {
1850
case RTW_ACT_SELF_PROTECTED_MESH_OPEN:
1851
case RTW_ACT_SELF_PROTECTED_MESH_CONF:
1852
case RTW_ACT_SELF_PROTECTED_MESH_CLOSE:
1853
case RTW_ACT_SELF_PROTECTED_MESH_GK_INFORM:
1854
case RTW_ACT_SELF_PROTECTED_MESH_GK_ACK:
1855
if (!(MLME_IS_MESH(adapter) && MLME_IS_ASOC(adapter)))
1856
goto exit;
1857
#ifdef CONFIG_IOCTL_CFG80211
1858
#if CONFIG_RTW_MACADDR_ACL
1859
if (rtw_access_ctrl(adapter, get_addr2_ptr(pframe)) == _FALSE)
1860
goto exit;
1861
#endif
1862
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
1863
if (rtw_mesh_cto_mgate_required(adapter)
1864
/* only peer being added (checked by notify conditions) is allowed */
1865
&& !rtw_mesh_plink_get(adapter, get_addr2_ptr(pframe)))
1866
goto exit;
1867
#endif
1868
rtw_cfg80211_rx_action(adapter, rframe, NULL);
1869
ret = _SUCCESS;
1870
#endif /* CONFIG_IOCTL_CFG80211 */
1871
break;
1872
default:
1873
break;
1874
}
1875
1876
exit:
1877
return ret;
1878
}
1879
1880
const u8 ae_to_mesh_ctrl_len[] = {
1881
6,
1882
12, /* MESH_FLAGS_AE_A4 */
1883
18, /* MESH_FLAGS_AE_A5_A6 */
1884
0,
1885
};
1886
1887
unsigned int on_action_mesh(_adapter *adapter, union recv_frame *rframe)
1888
{
1889
unsigned int ret = _FAIL;
1890
struct sta_info *sta = NULL;
1891
struct sta_priv *stapriv = &adapter->stapriv;
1892
u8 *pframe = rframe->u.hdr.rx_data;
1893
uint frame_len = rframe->u.hdr.len;
1894
u8 *frame_body = (u8 *)(pframe + sizeof(struct rtw_ieee80211_hdr_3addr));
1895
u8 category;
1896
u8 action;
1897
1898
if (!MLME_IS_MESH(adapter))
1899
goto exit;
1900
1901
/* check stainfo exist? */
1902
1903
category = frame_body[0];
1904
if (category != RTW_WLAN_CATEGORY_MESH)
1905
goto exit;
1906
1907
action = frame_body[1];
1908
switch (action) {
1909
case RTW_ACT_MESH_HWMP_PATH_SELECTION:
1910
rtw_mesh_rx_path_sel_frame(adapter, rframe);
1911
ret = _SUCCESS;
1912
break;
1913
default:
1914
break;
1915
}
1916
1917
exit:
1918
return ret;
1919
}
1920
1921
bool rtw_mesh_update_bss_peering_status(_adapter *adapter, WLAN_BSSID_EX *bss)
1922
{
1923
struct sta_priv *stapriv = &adapter->stapriv;
1924
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
1925
struct rtw_mesh_info *minfo = &adapter->mesh_info;
1926
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
1927
u8 num_of_peerings = stapriv->asoc_list_cnt;
1928
bool accept_peerings = stapriv->asoc_list_cnt < mcfg->max_peer_links;
1929
u8 *ie;
1930
int ie_len;
1931
bool updated = 0;
1932
1933
#if CONFIG_RTW_MESH_ACNODE_PREVENT
1934
accept_peerings |= plink_ctl->acnode_rsvd;
1935
#endif
1936
1937
ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len, BSS_EX_TLV_IES_LEN(bss));
1938
if (!ie || ie_len != 7) {
1939
rtw_warn_on(1);
1940
goto exit;
1941
}
1942
1943
if (GET_MESH_CONF_ELE_NUM_OF_PEERINGS(ie + 2) != num_of_peerings) {
1944
SET_MESH_CONF_ELE_NUM_OF_PEERINGS(ie + 2, num_of_peerings);
1945
updated = 1;
1946
}
1947
1948
if (GET_MESH_CONF_ELE_ACCEPT_PEERINGS(ie + 2) != accept_peerings) {
1949
SET_MESH_CONF_ELE_ACCEPT_PEERINGS(ie + 2, accept_peerings);
1950
updated = 1;
1951
}
1952
1953
exit:
1954
return updated;
1955
}
1956
1957
bool rtw_mesh_update_bss_formation_info(_adapter *adapter, WLAN_BSSID_EX *bss)
1958
{
1959
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
1960
struct rtw_mesh_info *minfo = &adapter->mesh_info;
1961
u8 cto_mgate = (minfo->num_gates || mcfg->dot11MeshGateAnnouncementProtocol);
1962
u8 cto_as = 0;
1963
u8 *ie;
1964
int ie_len;
1965
bool updated = 0;
1966
1967
ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
1968
BSS_EX_TLV_IES_LEN(bss));
1969
if (!ie || ie_len != 7) {
1970
rtw_warn_on(1);
1971
goto exit;
1972
}
1973
1974
if (GET_MESH_CONF_ELE_CTO_MGATE(ie + 2) != cto_mgate) {
1975
SET_MESH_CONF_ELE_CTO_MGATE(ie + 2, cto_mgate);
1976
updated = 1;
1977
}
1978
1979
if (GET_MESH_CONF_ELE_CTO_AS(ie + 2) != cto_as) {
1980
SET_MESH_CONF_ELE_CTO_AS(ie + 2, cto_as);
1981
updated = 1;
1982
}
1983
1984
exit:
1985
return updated;
1986
}
1987
1988
bool rtw_mesh_update_bss_forwarding_state(_adapter *adapter, WLAN_BSSID_EX *bss)
1989
{
1990
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
1991
u8 forward = mcfg->dot11MeshForwarding;
1992
u8 *ie;
1993
int ie_len;
1994
bool updated = 0;
1995
1996
ie = rtw_get_ie(BSS_EX_TLV_IES(bss), WLAN_EID_MESH_CONFIG, &ie_len,
1997
BSS_EX_TLV_IES_LEN(bss));
1998
if (!ie || ie_len != 7) {
1999
rtw_warn_on(1);
2000
goto exit;
2001
}
2002
2003
if (GET_MESH_CONF_ELE_FORWARDING(ie + 2) != forward) {
2004
SET_MESH_CONF_ELE_FORWARDING(ie + 2, forward);
2005
updated = 1;
2006
}
2007
2008
exit:
2009
return updated;
2010
}
2011
2012
struct mesh_plink_ent *_rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr)
2013
{
2014
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2015
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2016
struct mesh_plink_ent *ent = NULL;
2017
int i;
2018
2019
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
2020
if (plink_ctl->ent[i].valid == _TRUE
2021
&& _rtw_memcmp(plink_ctl->ent[i].addr, hwaddr, ETH_ALEN) == _TRUE
2022
) {
2023
ent = &plink_ctl->ent[i];
2024
break;
2025
}
2026
}
2027
2028
return ent;
2029
}
2030
2031
struct mesh_plink_ent *rtw_mesh_plink_get(_adapter *adapter, const u8 *hwaddr)
2032
{
2033
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2034
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2035
struct mesh_plink_ent *ent = NULL;
2036
_irqL irqL;
2037
2038
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2039
ent = _rtw_mesh_plink_get(adapter, hwaddr);
2040
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2041
2042
return ent;
2043
}
2044
2045
struct mesh_plink_ent *rtw_mesh_plink_get_no_estab_by_idx(_adapter *adapter, u8 idx)
2046
{
2047
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2048
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2049
struct mesh_plink_ent *ent = NULL;
2050
int i, j = 0;
2051
_irqL irqL;
2052
2053
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2054
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
2055
if (plink_ctl->ent[i].valid == _TRUE
2056
&& plink_ctl->ent[i].plink_state != RTW_MESH_PLINK_ESTAB
2057
) {
2058
if (j == idx) {
2059
ent = &plink_ctl->ent[i];
2060
break;
2061
}
2062
j++;
2063
}
2064
}
2065
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2066
2067
return ent;
2068
}
2069
2070
int _rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr)
2071
{
2072
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2073
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2074
struct mesh_plink_ent *ent = NULL;
2075
u8 exist = _FALSE;
2076
int i;
2077
2078
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
2079
if (plink_ctl->ent[i].valid == _TRUE
2080
&& _rtw_memcmp(plink_ctl->ent[i].addr, hwaddr, ETH_ALEN) == _TRUE
2081
) {
2082
ent = &plink_ctl->ent[i];
2083
exist = _TRUE;
2084
break;
2085
}
2086
2087
if (ent == NULL && plink_ctl->ent[i].valid == _FALSE)
2088
ent = &plink_ctl->ent[i];
2089
}
2090
2091
if (exist == _FALSE && ent) {
2092
_rtw_memcpy(ent->addr, hwaddr, ETH_ALEN);
2093
ent->valid = _TRUE;
2094
#ifdef CONFIG_RTW_MESH_AEK
2095
ent->aek_valid = 0;
2096
#endif
2097
ent->llid = 0;
2098
ent->plid = 0;
2099
_rtw_memset(ent->chosen_pmk, 0, 16);
2100
#ifdef CONFIG_RTW_MESH_AEK
2101
_rtw_memset(ent->sel_pcs, 0, 4);
2102
_rtw_memset(ent->l_nonce, 0, 32);
2103
_rtw_memset(ent->p_nonce, 0, 32);
2104
#endif
2105
ent->plink_state = RTW_MESH_PLINK_LISTEN;
2106
#ifndef CONFIG_RTW_MESH_DRIVER_AID
2107
ent->aid = 0;
2108
#endif
2109
ent->peer_aid = 0;
2110
SET_PEER_CONF_DISABLED(ent);
2111
SET_CTO_MGATE_CONF_DISABLED(ent);
2112
plink_ctl->num++;
2113
}
2114
2115
return exist == _TRUE ? RTW_ALREADY : (ent ? _SUCCESS : _FAIL);
2116
}
2117
2118
int rtw_mesh_plink_add(_adapter *adapter, const u8 *hwaddr)
2119
{
2120
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2121
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2122
_irqL irqL;
2123
int ret;
2124
2125
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2126
ret = _rtw_mesh_plink_add(adapter, hwaddr);
2127
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2128
2129
return ret;
2130
}
2131
2132
int rtw_mesh_plink_set_state(_adapter *adapter, const u8 *hwaddr, u8 state)
2133
{
2134
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2135
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2136
struct mesh_plink_ent *ent = NULL;
2137
_irqL irqL;
2138
2139
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2140
ent = _rtw_mesh_plink_get(adapter, hwaddr);
2141
if (ent)
2142
ent->plink_state = state;
2143
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2144
2145
return ent ? _SUCCESS : _FAIL;
2146
}
2147
2148
#ifdef CONFIG_RTW_MESH_AEK
2149
int rtw_mesh_plink_set_aek(_adapter *adapter, const u8 *hwaddr, const u8 *aek)
2150
{
2151
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2152
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2153
struct mesh_plink_ent *ent = NULL;
2154
_irqL irqL;
2155
2156
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2157
ent = _rtw_mesh_plink_get(adapter, hwaddr);
2158
if (ent) {
2159
_rtw_memcpy(ent->aek, aek, 32);
2160
ent->aek_valid = 1;
2161
}
2162
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2163
2164
return ent ? _SUCCESS : _FAIL;
2165
}
2166
#endif
2167
2168
#if CONFIG_RTW_MESH_PEER_BLACKLIST
2169
int rtw_mesh_plink_set_peer_conf_timeout(_adapter *adapter, const u8 *hwaddr)
2170
{
2171
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
2172
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2173
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2174
struct mesh_plink_ent *ent = NULL;
2175
_irqL irqL;
2176
2177
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2178
ent = _rtw_mesh_plink_get(adapter, hwaddr);
2179
if (ent) {
2180
if (IS_PEER_CONF_DISABLED(ent))
2181
SET_PEER_CONF_END_TIME(ent, mcfg->peer_sel_policy.peer_conf_timeout_ms);
2182
}
2183
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2184
2185
return ent ? _SUCCESS : _FAIL;
2186
}
2187
#endif
2188
2189
void _rtw_mesh_plink_del_ent(_adapter *adapter, struct mesh_plink_ent *ent)
2190
{
2191
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2192
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2193
2194
ent->valid = _FALSE;
2195
#ifdef CONFIG_RTW_MESH_DRIVER_AID
2196
if (ent->tx_conf_ies && ent->tx_conf_ies_len)
2197
rtw_mfree(ent->tx_conf_ies, ent->tx_conf_ies_len);
2198
ent->tx_conf_ies = NULL;
2199
ent->tx_conf_ies_len = 0;
2200
#endif
2201
if (ent->rx_conf_ies && ent->rx_conf_ies_len)
2202
rtw_mfree(ent->rx_conf_ies, ent->rx_conf_ies_len);
2203
ent->rx_conf_ies = NULL;
2204
ent->rx_conf_ies_len = 0;
2205
if (ent->scanned)
2206
ent->scanned = NULL;
2207
plink_ctl->num--;
2208
}
2209
2210
int rtw_mesh_plink_del(_adapter *adapter, const u8 *hwaddr)
2211
{
2212
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2213
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2214
struct mesh_plink_ent *ent = NULL;
2215
u8 exist = _FALSE;
2216
int i;
2217
_irqL irqL;
2218
2219
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2220
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
2221
if (plink_ctl->ent[i].valid == _TRUE
2222
&& _rtw_memcmp(plink_ctl->ent[i].addr, hwaddr, ETH_ALEN) == _TRUE
2223
) {
2224
ent = &plink_ctl->ent[i];
2225
exist = _TRUE;
2226
break;
2227
}
2228
}
2229
2230
if (exist == _TRUE)
2231
_rtw_mesh_plink_del_ent(adapter, ent);
2232
2233
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2234
2235
return exist == _TRUE ? _SUCCESS : RTW_ALREADY;
2236
}
2237
2238
void rtw_mesh_plink_ctl_init(_adapter *adapter)
2239
{
2240
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2241
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2242
int i;
2243
2244
_rtw_spinlock_init(&plink_ctl->lock);
2245
plink_ctl->num = 0;
2246
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++)
2247
plink_ctl->ent[i].valid = _FALSE;
2248
2249
#if CONFIG_RTW_MESH_PEER_BLACKLIST
2250
_rtw_init_queue(&plink_ctl->peer_blacklist);
2251
#endif
2252
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
2253
_rtw_init_queue(&plink_ctl->cto_mgate_blacklist);
2254
#endif
2255
}
2256
2257
void rtw_mesh_plink_ctl_deinit(_adapter *adapter)
2258
{
2259
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2260
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2261
struct mesh_plink_ent *ent;
2262
int i;
2263
_irqL irqL;
2264
2265
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2266
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
2267
ent = &plink_ctl->ent[i];
2268
#ifdef CONFIG_RTW_MESH_DRIVER_AID
2269
if (ent->tx_conf_ies && ent->tx_conf_ies_len)
2270
rtw_mfree(ent->tx_conf_ies, ent->tx_conf_ies_len);
2271
#endif
2272
if (ent->rx_conf_ies && ent->rx_conf_ies_len)
2273
rtw_mfree(ent->rx_conf_ies, ent->rx_conf_ies_len);
2274
}
2275
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2276
2277
_rtw_spinlock_free(&plink_ctl->lock);
2278
2279
#if CONFIG_RTW_MESH_PEER_BLACKLIST
2280
rtw_mesh_peer_blacklist_flush(adapter);
2281
_rtw_deinit_queue(&plink_ctl->peer_blacklist);
2282
#endif
2283
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
2284
rtw_mesh_cto_mgate_blacklist_flush(adapter);
2285
_rtw_deinit_queue(&plink_ctl->cto_mgate_blacklist);
2286
#endif
2287
}
2288
2289
void dump_mesh_plink_ctl(void *sel, _adapter *adapter)
2290
{
2291
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2292
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2293
struct mesh_plink_ent *ent;
2294
int i;
2295
2296
RTW_PRINT_SEL(sel, "num:%u\n", plink_ctl->num);
2297
#if CONFIG_RTW_MESH_ACNODE_PREVENT
2298
RTW_PRINT_SEL(sel, "acnode_rsvd:%u\n", plink_ctl->acnode_rsvd);
2299
#endif
2300
2301
for (i = 0; i < RTW_MESH_MAX_PEER_CANDIDATES; i++) {
2302
ent = &plink_ctl->ent[i];
2303
if (!ent->valid)
2304
continue;
2305
2306
RTW_PRINT_SEL(sel, "\n");
2307
RTW_PRINT_SEL(sel, "peer:"MAC_FMT"\n", MAC_ARG(ent->addr));
2308
RTW_PRINT_SEL(sel, "plink_state:%s\n", rtw_mesh_plink_str(ent->plink_state));
2309
2310
#ifdef CONFIG_RTW_MESH_AEK
2311
if (ent->aek_valid)
2312
RTW_PRINT_SEL(sel, "aek:"KEY_FMT KEY_FMT"\n", KEY_ARG(ent->aek), KEY_ARG(ent->aek + 16));
2313
#endif
2314
2315
RTW_PRINT_SEL(sel, "llid:%u, plid:%u\n", ent->llid, ent->plid);
2316
#ifndef CONFIG_RTW_MESH_DRIVER_AID
2317
RTW_PRINT_SEL(sel, "aid:%u\n", ent->aid);
2318
#endif
2319
RTW_PRINT_SEL(sel, "peer_aid:%u\n", ent->peer_aid);
2320
2321
RTW_PRINT_SEL(sel, "chosen_pmk:"KEY_FMT"\n", KEY_ARG(ent->chosen_pmk));
2322
2323
#ifdef CONFIG_RTW_MESH_AEK
2324
RTW_PRINT_SEL(sel, "sel_pcs:%02x%02x%02x%02x\n"
2325
, ent->sel_pcs[0], ent->sel_pcs[1], ent->sel_pcs[2], ent->sel_pcs[3]);
2326
RTW_PRINT_SEL(sel, "l_nonce:"KEY_FMT KEY_FMT"\n", KEY_ARG(ent->l_nonce), KEY_ARG(ent->l_nonce + 16));
2327
RTW_PRINT_SEL(sel, "p_nonce:"KEY_FMT KEY_FMT"\n", KEY_ARG(ent->p_nonce), KEY_ARG(ent->p_nonce + 16));
2328
#endif
2329
2330
#ifdef CONFIG_RTW_MESH_DRIVER_AID
2331
RTW_PRINT_SEL(sel, "tx_conf_ies:%p, len:%u\n", ent->tx_conf_ies, ent->tx_conf_ies_len);
2332
#endif
2333
RTW_PRINT_SEL(sel, "rx_conf_ies:%p, len:%u\n", ent->rx_conf_ies, ent->rx_conf_ies_len);
2334
RTW_PRINT_SEL(sel, "scanned:%p\n", ent->scanned);
2335
2336
#if CONFIG_RTW_MESH_PEER_BLACKLIST
2337
if (!IS_PEER_CONF_DISABLED(ent)) {
2338
if (!IS_PEER_CONF_TIMEOUT(ent))
2339
RTW_PRINT_SEL(sel, "peer_conf:%d\n", rtw_systime_to_ms(ent->peer_conf_end_time - rtw_get_current_time()));
2340
else
2341
RTW_PRINT_SEL(sel, "peer_conf:TIMEOUT\n");
2342
}
2343
#endif
2344
2345
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
2346
if (!IS_CTO_MGATE_CONF_DISABLED(ent)) {
2347
if (!IS_CTO_MGATE_CONF_TIMEOUT(ent))
2348
RTW_PRINT_SEL(sel, "cto_mgate_conf:%d\n", rtw_systime_to_ms(ent->cto_mgate_conf_end_time - rtw_get_current_time()));
2349
else
2350
RTW_PRINT_SEL(sel, "cto_mgate_conf:TIMEOUT\n");
2351
}
2352
#endif
2353
}
2354
}
2355
2356
/* this function is called with plink_ctl being locked */
2357
int rtw_mesh_peer_establish(_adapter *adapter, struct mesh_plink_ent *plink, struct sta_info *sta)
2358
{
2359
#ifndef DBG_RTW_MESH_PEER_ESTABLISH
2360
#define DBG_RTW_MESH_PEER_ESTABLISH 0
2361
#endif
2362
2363
struct sta_priv *stapriv = &adapter->stapriv;
2364
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
2365
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2366
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2367
u8 *tlv_ies;
2368
u16 tlv_ieslen;
2369
struct rtw_ieee802_11_elems elems;
2370
_irqL irqL;
2371
int i;
2372
int ret = _FAIL;
2373
2374
if (!plink->rx_conf_ies || !plink->rx_conf_ies_len) {
2375
RTW_INFO(FUNC_ADPT_FMT" no rx confirm from sta "MAC_FMT"\n"
2376
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
2377
goto exit;
2378
}
2379
2380
if (plink->rx_conf_ies_len < 4) {
2381
RTW_INFO(FUNC_ADPT_FMT" confirm from sta "MAC_FMT" too short\n"
2382
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
2383
goto exit;
2384
}
2385
2386
#ifdef CONFIG_RTW_MESH_DRIVER_AID
2387
if (!plink->tx_conf_ies || !plink->tx_conf_ies_len) {
2388
RTW_INFO(FUNC_ADPT_FMT" no tx confirm to sta "MAC_FMT"\n"
2389
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
2390
goto exit;
2391
}
2392
2393
if (plink->tx_conf_ies_len < 4) {
2394
RTW_INFO(FUNC_ADPT_FMT" confirm to sta "MAC_FMT" too short\n"
2395
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
2396
goto exit;
2397
}
2398
#endif
2399
2400
tlv_ies = plink->rx_conf_ies + 4;
2401
tlv_ieslen = plink->rx_conf_ies_len - 4;
2402
2403
if (DBG_RTW_MESH_PEER_ESTABLISH)
2404
dump_ies(RTW_DBGDUMP, tlv_ies, tlv_ieslen);
2405
2406
if (rtw_ieee802_11_parse_elems(tlv_ies, tlv_ieslen, &elems, 1) == ParseFailed) {
2407
RTW_INFO(FUNC_ADPT_FMT" sta "MAC_FMT" sent invalid confirm\n"
2408
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr));
2409
goto exit;
2410
}
2411
2412
SET_PEER_CONF_DISABLED(plink);
2413
if (rtw_bss_is_cto_mgate(&plink->scanned->network)
2414
&& !rtw_bss_is_forwarding(&plink->scanned->network))
2415
SET_CTO_MGATE_CONF_END_TIME(plink, mcfg->peer_sel_policy.cto_mgate_conf_timeout_ms);
2416
else
2417
SET_CTO_MGATE_CONF_DISABLED(plink);
2418
2419
sta->state &= (~WIFI_FW_AUTH_SUCCESS);
2420
sta->state |= WIFI_FW_ASSOC_STATE;
2421
2422
rtw_ap_parse_sta_capability(adapter, sta, plink->rx_conf_ies);
2423
2424
if (rtw_ap_parse_sta_supported_rates(adapter, sta, tlv_ies, tlv_ieslen) != _STATS_SUCCESSFUL_)
2425
goto exit;
2426
2427
if (rtw_ap_parse_sta_security_ie(adapter, sta, &elems) != _STATS_SUCCESSFUL_)
2428
goto exit;
2429
2430
rtw_ap_parse_sta_wmm_ie(adapter, sta, tlv_ies, tlv_ieslen);
2431
#ifdef CONFIG_RTS_FULL_BW
2432
/*check vendor IE*/
2433
rtw_parse_sta_vendor_ie_8812(adapter, sta, tlv_ies, tlv_ieslen);
2434
#endif/*CONFIG_RTS_FULL_BW*/
2435
2436
rtw_ap_parse_sta_ht_ie(adapter, sta, &elems);
2437
rtw_ap_parse_sta_vht_ie(adapter, sta, &elems);
2438
2439
/* AID */
2440
#ifdef CONFIG_RTW_MESH_DRIVER_AID
2441
sta->cmn.aid = RTW_GET_LE16(plink->tx_conf_ies + 2);
2442
#else
2443
sta->cmn.aid = plink->aid;
2444
#endif
2445
stapriv->sta_aid[sta->cmn.aid - 1] = sta;
2446
RTW_INFO(FUNC_ADPT_FMT" sta "MAC_FMT" aid:%u\n"
2447
, FUNC_ADPT_ARG(adapter), MAC_ARG(sta->cmn.mac_addr), sta->cmn.aid);
2448
2449
sta->state &= (~WIFI_FW_ASSOC_STATE);
2450
sta->state |= WIFI_FW_ASSOC_SUCCESS;
2451
2452
sta->local_mps = RTW_MESH_PS_ACTIVE;
2453
2454
rtw_ewma_err_rate_init(&sta->metrics.err_rate);
2455
rtw_ewma_err_rate_add(&sta->metrics.err_rate, 1);
2456
/* init data_rate to 1M */
2457
sta->metrics.data_rate = 10;
2458
sta->alive = _TRUE;
2459
2460
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
2461
if (rtw_is_list_empty(&sta->asoc_list)) {
2462
STA_SET_MESH_PLINK(sta, plink);
2463
/* TBD: up layer timeout mechanism */
2464
/* sta->expire_to = mcfg->plink_timeout / 2; */
2465
rtw_list_insert_tail(&sta->asoc_list, &stapriv->asoc_list);
2466
stapriv->asoc_list_cnt++;
2467
}
2468
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
2469
2470
bss_cap_update_on_sta_join(adapter, sta);
2471
sta_info_update(adapter, sta);
2472
report_add_sta_event(adapter, sta->cmn.mac_addr);
2473
2474
ret = _SUCCESS;
2475
2476
exit:
2477
return ret;
2478
}
2479
2480
void rtw_mesh_expire_peer_notify(_adapter *adapter, const u8 *peer_addr)
2481
{
2482
u8 null_ssid[2] = {0, 0};
2483
2484
#ifdef CONFIG_IOCTL_CFG80211
2485
rtw_cfg80211_notify_new_peer_candidate(adapter->rtw_wdev
2486
, peer_addr
2487
, null_ssid
2488
, 2
2489
, GFP_ATOMIC
2490
);
2491
#endif
2492
2493
return;
2494
}
2495
2496
static u8 *rtw_mesh_construct_peer_mesh_close(_adapter *adapter, struct mesh_plink_ent *plink, u16 reason, u32 *len)
2497
{
2498
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2499
u8 *frame = NULL, *pos;
2500
u32 flen;
2501
struct rtw_ieee80211_hdr *whdr;
2502
2503
if (minfo->mesh_auth_id && !MESH_PLINK_AEK_VALID(plink))
2504
goto exit;
2505
2506
flen = sizeof(struct rtw_ieee80211_hdr_3addr)
2507
+ 2 /* category, action */
2508
+ 2 + minfo->mesh_id_len /* mesh id */
2509
+ 2 + 8 + (minfo->mesh_auth_id ? 16 : 0) /* mpm */
2510
+ (minfo->mesh_auth_id ? 2 + AES_BLOCK_SIZE : 0) /* mic */
2511
+ (minfo->mesh_auth_id ? 70 : 0) /* ampe */
2512
;
2513
2514
pos = frame = rtw_zmalloc(flen);
2515
if (!frame)
2516
goto exit;
2517
2518
whdr = (struct rtw_ieee80211_hdr *)frame;
2519
_rtw_memcpy(whdr->addr1, adapter_mac_addr(adapter), ETH_ALEN);
2520
_rtw_memcpy(whdr->addr2, plink->addr, ETH_ALEN);
2521
_rtw_memcpy(whdr->addr3, adapter_mac_addr(adapter), ETH_ALEN);
2522
2523
set_frame_sub_type(frame, WIFI_ACTION);
2524
2525
pos += sizeof(struct rtw_ieee80211_hdr_3addr);
2526
*(pos++) = RTW_WLAN_CATEGORY_SELF_PROTECTED;
2527
*(pos++) = RTW_ACT_SELF_PROTECTED_MESH_CLOSE;
2528
2529
pos = rtw_set_ie_mesh_id(pos, NULL, minfo->mesh_id, minfo->mesh_id_len);
2530
2531
pos = rtw_set_ie_mpm(pos, NULL
2532
, minfo->mesh_auth_id ? 1 : 0
2533
, plink->plid
2534
, &plink->llid
2535
, &reason
2536
, minfo->mesh_auth_id ? plink->chosen_pmk : NULL);
2537
2538
#ifdef CONFIG_RTW_MESH_AEK
2539
if (minfo->mesh_auth_id) {
2540
u8 ampe_buf[70];
2541
int enc_ret;
2542
2543
*pos = WLAN_EID_MIC;
2544
*(pos + 1) = AES_BLOCK_SIZE;
2545
2546
ampe_buf[0] = WLAN_EID_AMPE;
2547
ampe_buf[1] = 68;
2548
_rtw_memcpy(ampe_buf + 2, plink->sel_pcs, 4);
2549
_rtw_memcpy(ampe_buf + 6, plink->p_nonce, 32);
2550
_rtw_memcpy(ampe_buf + 38, plink->l_nonce, 32);
2551
2552
enc_ret = rtw_mpm_ampe_enc(adapter, plink
2553
, frame + sizeof(struct rtw_ieee80211_hdr_3addr)
2554
, pos, ampe_buf, 1);
2555
if (enc_ret != _SUCCESS) {
2556
rtw_mfree(frame, flen);
2557
frame = NULL;
2558
goto exit;
2559
}
2560
}
2561
#endif
2562
2563
*len = flen;
2564
2565
exit:
2566
return frame;
2567
}
2568
2569
void _rtw_mesh_expire_peer_ent(_adapter *adapter, struct mesh_plink_ent *plink)
2570
{
2571
#if defined(CONFIG_RTW_MESH_STA_DEL_DISASOC)
2572
_rtw_mesh_plink_del_ent(adapter, plink);
2573
rtw_cfg80211_indicate_sta_disassoc(adapter, plink->addr, 0);
2574
#else
2575
u8 *frame = NULL;
2576
u32 flen;
2577
2578
if (plink->plink_state == RTW_MESH_PLINK_ESTAB)
2579
frame = rtw_mesh_construct_peer_mesh_close(adapter, plink, WLAN_REASON_MESH_CLOSE, &flen);
2580
2581
if (frame) {
2582
struct mlme_ext_priv *mlmeext = &adapter->mlmeextpriv;
2583
struct wireless_dev *wdev = adapter->rtw_wdev;
2584
s32 freq = rtw_ch2freq(mlmeext->cur_channel);
2585
2586
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37)) || defined(COMPAT_KERNEL_RELEASE)
2587
rtw_cfg80211_rx_mgmt(wdev, freq, 0, frame, flen, GFP_ATOMIC);
2588
#else
2589
cfg80211_rx_action(adapter->pnetdev, freq, frame, flen, GFP_ATOMIC);
2590
#endif
2591
2592
rtw_mfree(frame, flen);
2593
} else {
2594
rtw_mesh_expire_peer_notify(adapter, plink->addr);
2595
RTW_INFO(FUNC_ADPT_FMT" set "MAC_FMT" plink unknown\n"
2596
, FUNC_ADPT_ARG(adapter), MAC_ARG(plink->addr));
2597
plink->plink_state = RTW_MESH_PLINK_UNKNOWN;
2598
}
2599
#endif
2600
}
2601
2602
void rtw_mesh_expire_peer(_adapter *adapter, const u8 *peer_addr)
2603
{
2604
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2605
struct mesh_plink_pool *plink_ctl = &minfo->plink_ctl;
2606
struct mesh_plink_ent *plink;
2607
_irqL irqL;
2608
2609
_enter_critical_bh(&(plink_ctl->lock), &irqL);
2610
2611
plink = _rtw_mesh_plink_get(adapter, peer_addr);
2612
if (!plink)
2613
goto exit;
2614
2615
_rtw_mesh_expire_peer_ent(adapter, plink);
2616
2617
exit:
2618
_exit_critical_bh(&(plink_ctl->lock), &irqL);
2619
}
2620
2621
u8 rtw_mesh_ps_annc(_adapter *adapter, u8 ps)
2622
{
2623
_irqL irqL;
2624
_list *head, *list;
2625
struct sta_info *sta;
2626
struct sta_priv *stapriv = &adapter->stapriv;
2627
u8 sta_alive_num = 0, i;
2628
char sta_alive_list[NUM_STA];
2629
u8 annc_cnt = 0;
2630
2631
if (rtw_linked_check(adapter) == _FALSE)
2632
goto exit;
2633
2634
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
2635
2636
head = &stapriv->asoc_list;
2637
list = get_next(head);
2638
while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
2639
int stainfo_offset;
2640
2641
sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
2642
list = get_next(list);
2643
2644
stainfo_offset = rtw_stainfo_offset(stapriv, sta);
2645
if (stainfo_offset_valid(stainfo_offset))
2646
sta_alive_list[sta_alive_num++] = stainfo_offset;
2647
}
2648
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
2649
2650
for (i = 0; i < sta_alive_num; i++) {
2651
sta = rtw_get_stainfo_by_offset(stapriv, sta_alive_list[i]);
2652
if (!sta)
2653
continue;
2654
2655
issue_qos_nulldata(adapter, sta->cmn.mac_addr, 7, ps, 3, 500);
2656
annc_cnt++;
2657
}
2658
2659
exit:
2660
return annc_cnt;
2661
}
2662
2663
static void mpath_tx_tasklet_hdl(void *priv)
2664
{
2665
_adapter *adapter = (_adapter *)priv;
2666
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2667
struct xmit_frame *xframe;
2668
_list *list, *head;
2669
_list tmp;
2670
u32 tmp_len;
2671
s32 res;
2672
2673
_rtw_init_listhead(&tmp);
2674
2675
while (1) {
2676
tmp_len = 0;
2677
enter_critical_bh(&minfo->mpath_tx_queue.lock);
2678
if (minfo->mpath_tx_queue_len) {
2679
rtw_list_splice_init(&minfo->mpath_tx_queue.queue, &tmp);
2680
tmp_len = minfo->mpath_tx_queue_len;
2681
minfo->mpath_tx_queue_len = 0;
2682
}
2683
exit_critical_bh(&minfo->mpath_tx_queue.lock);
2684
2685
if (!tmp_len)
2686
break;
2687
2688
head = &tmp;
2689
list = get_next(head);
2690
while (rtw_end_of_queue_search(head, list) == _FALSE) {
2691
xframe = LIST_CONTAINOR(list, struct xmit_frame, list);
2692
list = get_next(list);
2693
rtw_list_delete(&xframe->list);
2694
res = rtw_xmit_posthandle(adapter, xframe, xframe->pkt);
2695
if (res < 0) {
2696
#ifdef DBG_TX_DROP_FRAME
2697
RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit fail\n", __FUNCTION__);
2698
#endif
2699
adapter->xmitpriv.tx_drop++;
2700
}
2701
}
2702
}
2703
}
2704
2705
static void rtw_mpath_tx_queue_flush(_adapter *adapter)
2706
{
2707
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2708
struct xmit_frame *xframe;
2709
_list *list, *head;
2710
_list tmp;
2711
2712
_rtw_init_listhead(&tmp);
2713
2714
enter_critical_bh(&minfo->mpath_tx_queue.lock);
2715
rtw_list_splice_init(&minfo->mpath_tx_queue.queue, &tmp);
2716
minfo->mpath_tx_queue_len = 0;
2717
exit_critical_bh(&minfo->mpath_tx_queue.lock);
2718
2719
head = &tmp;
2720
list = get_next(head);
2721
while (rtw_end_of_queue_search(head, list) == _FALSE) {
2722
xframe = LIST_CONTAINOR(list, struct xmit_frame, list);
2723
list = get_next(list);
2724
rtw_list_delete(&xframe->list);
2725
rtw_free_xmitframe(&adapter->xmitpriv, xframe);
2726
}
2727
}
2728
2729
#ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
2730
#if defined(CONFIG_SLUB)
2731
#include <linux/slub_def.h>
2732
#elif defined(CONFIG_SLAB)
2733
#include <linux/slab_def.h>
2734
#endif
2735
typedef struct kmem_cache rtw_mcache;
2736
#endif
2737
2738
rtw_mcache *rtw_mcache_create(const char *name, size_t size)
2739
{
2740
#ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
2741
return kmem_cache_create(name, size, 0, 0, NULL);
2742
#else
2743
#error "TBD\n";
2744
#endif
2745
}
2746
2747
void rtw_mcache_destroy(rtw_mcache *s)
2748
{
2749
#ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
2750
kmem_cache_destroy(s);
2751
#else
2752
#error "TBD\n";
2753
#endif
2754
}
2755
2756
void *_rtw_mcache_alloc(rtw_mcache *cachep)
2757
{
2758
#ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
2759
return kmem_cache_alloc(cachep, GFP_ATOMIC);
2760
#else
2761
#error "TBD\n";
2762
#endif
2763
}
2764
2765
void _rtw_mcache_free(rtw_mcache *cachep, void *objp)
2766
{
2767
#ifdef PLATFORM_LINUX /* 3.10 ~ 4.13 checked */
2768
kmem_cache_free(cachep, objp);
2769
#else
2770
#error "TBD\n";
2771
#endif
2772
}
2773
2774
#ifdef DBG_MEM_ALLOC
2775
inline void *dbg_rtw_mcache_alloc(rtw_mcache *cachep, const enum mstat_f flags, const char *func, const int line)
2776
{
2777
void *p;
2778
u32 sz = cachep->size;
2779
2780
if (match_mstat_sniff_rules(flags, sz))
2781
RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%u)\n", func, line, __func__, sz);
2782
2783
p = _rtw_mcache_alloc(cachep);
2784
2785
rtw_mstat_update(
2786
flags
2787
, p ? MSTAT_ALLOC_SUCCESS : MSTAT_ALLOC_FAIL
2788
, sz
2789
);
2790
2791
return p;
2792
}
2793
2794
inline void dbg_rtw_mcache_free(rtw_mcache *cachep, void *pbuf, const enum mstat_f flags, const char *func, const int line)
2795
{
2796
u32 sz = cachep->size;
2797
2798
if (match_mstat_sniff_rules(flags, sz))
2799
RTW_INFO("DBG_MEM_ALLOC %s:%d %s(%u)\n", func, line, __func__, sz);
2800
2801
_rtw_mcache_free(cachep, pbuf);
2802
2803
rtw_mstat_update(
2804
flags
2805
, MSTAT_FREE
2806
, sz
2807
);
2808
}
2809
2810
#define rtw_mcache_alloc(cachep) dbg_rtw_mcache_alloc(cachep, MSTAT_TYPE_PHY, __FUNCTION__, __LINE__)
2811
#define rtw_mcache_free(cachep, objp) dbg_rtw_mcache_free(cachep, objp, MSTAT_TYPE_PHY, __FUNCTION__, __LINE__)
2812
#else
2813
#define rtw_mcache_alloc(cachep) _rtw_mcache_alloc(cachep)
2814
#define rtw_mcache_free(cachep, objp) _rtw_mcache_free(cachep, objp)
2815
#endif /* DBG_MEM_ALLOC */
2816
2817
/* Mesh Received Cache */
2818
#define RTW_MRC_BUCKETS 256 /* must be a power of 2 */
2819
#define RTW_MRC_QUEUE_MAX_LEN 4
2820
#define RTW_MRC_TIMEOUT_MS (3 * 1000)
2821
2822
/**
2823
* struct rtw_mrc_entry - entry in the Mesh Received Cache
2824
*
2825
* @seqnum: mesh sequence number of the frame
2826
* @exp_time: expiration time of the entry
2827
* @msa: mesh source address of the frame
2828
* @list: hashtable list pointer
2829
*
2830
* The Mesh Received Cache keeps track of the latest received frames that
2831
* have been received by a mesh interface and discards received frames
2832
* that are found in the cache.
2833
*/
2834
struct rtw_mrc_entry {
2835
rtw_hlist_node list;
2836
systime exp_time;
2837
u32 seqnum;
2838
u8 msa[ETH_ALEN];
2839
};
2840
2841
struct rtw_mrc {
2842
rtw_hlist_head bucket[RTW_MRC_BUCKETS];
2843
u32 idx_mask;
2844
rtw_mcache *cache;
2845
};
2846
2847
static int rtw_mrc_init(_adapter *adapter)
2848
{
2849
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2850
char cache_name[IFNAMSIZ + 8 + 1];
2851
int i;
2852
2853
minfo->mrc = rtw_malloc(sizeof(struct rtw_mrc));
2854
if (!minfo->mrc)
2855
return -ENOMEM;
2856
minfo->mrc->idx_mask = RTW_MRC_BUCKETS - 1;
2857
for (i = 0; i < RTW_MRC_BUCKETS; i++)
2858
rtw_hlist_head_init(&minfo->mrc->bucket[i]);
2859
2860
sprintf(cache_name, "rtw_mrc_%s", ADPT_ARG(adapter));
2861
minfo->mrc->cache = rtw_mcache_create(cache_name, sizeof(struct rtw_mrc_entry));
2862
2863
return 0;
2864
}
2865
2866
static void rtw_mrc_free(_adapter *adapter)
2867
{
2868
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2869
struct rtw_mrc *mrc = minfo->mrc;
2870
struct rtw_mrc_entry *p;
2871
rtw_hlist_node *np, *n;
2872
int i;
2873
2874
if (!mrc)
2875
return;
2876
2877
for (i = 0; i < RTW_MRC_BUCKETS; i++) {
2878
rtw_hlist_for_each_entry_safe(p, np, n, &mrc->bucket[i], list) {
2879
rtw_hlist_del(&p->list);
2880
rtw_mcache_free(mrc->cache, p);
2881
}
2882
}
2883
2884
rtw_mcache_destroy(mrc->cache);
2885
2886
rtw_mfree(mrc, sizeof(struct rtw_mrc));
2887
minfo->mrc = NULL;
2888
}
2889
2890
/**
2891
* rtw_mrc_check - Check frame in mesh received cache and add if absent.
2892
*
2893
* @adapter: interface
2894
* @msa: mesh source address
2895
* @seq: mesh seq number
2896
*
2897
* Returns: 0 if the frame is not in the cache, nonzero otherwise.
2898
*
2899
* Checks using the mesh source address and the mesh sequence number if we have
2900
* received this frame lately. If the frame is not in the cache, it is added to
2901
* it.
2902
*/
2903
static int rtw_mrc_check(_adapter *adapter, const u8 *msa, u32 seq)
2904
{
2905
struct rtw_mesh_info *minfo = &adapter->mesh_info;
2906
struct rtw_mrc *mrc = minfo->mrc;
2907
int entries = 0;
2908
u8 idx;
2909
struct rtw_mrc_entry *p;
2910
rtw_hlist_node *np, *n;
2911
u8 timeout;
2912
2913
if (!mrc)
2914
return -1;
2915
2916
idx = seq & mrc->idx_mask;
2917
rtw_hlist_for_each_entry_safe(p, np, n, &mrc->bucket[idx], list) {
2918
++entries;
2919
timeout = rtw_time_after(rtw_get_current_time(), p->exp_time);
2920
if (timeout || entries == RTW_MRC_QUEUE_MAX_LEN) {
2921
if (!timeout)
2922
minfo->mshstats.mrc_del_qlen++;
2923
2924
rtw_hlist_del(&p->list);
2925
rtw_mcache_free(mrc->cache, p);
2926
--entries;
2927
} else if ((seq == p->seqnum) && _rtw_memcmp(msa, p->msa, ETH_ALEN) == _TRUE)
2928
return -1;
2929
}
2930
2931
p = rtw_mcache_alloc(mrc->cache);
2932
if (!p)
2933
return 0;
2934
2935
p->seqnum = seq;
2936
p->exp_time = rtw_get_current_time() + rtw_ms_to_systime(RTW_MRC_TIMEOUT_MS);
2937
_rtw_memcpy(p->msa, msa, ETH_ALEN);
2938
rtw_hlist_add_head(&p->list, &mrc->bucket[idx]);
2939
return 0;
2940
}
2941
2942
static int rtw_mesh_decache(_adapter *adapter, const u8 *msa, u32 seq)
2943
{
2944
return rtw_mrc_check(adapter, msa, seq);
2945
}
2946
2947
#ifndef RTW_MESH_SCAN_RESULT_EXP_MS
2948
#define RTW_MESH_SCAN_RESULT_EXP_MS (10 * 1000)
2949
#endif
2950
2951
#ifndef RTW_MESH_ACNODE_PREVENT
2952
#define RTW_MESH_ACNODE_PREVENT 0
2953
#endif
2954
#ifndef RTW_MESH_ACNODE_CONF_TIMEOUT_MS
2955
#define RTW_MESH_ACNODE_CONF_TIMEOUT_MS (20 * 1000)
2956
#endif
2957
#ifndef RTW_MESH_ACNODE_NOTIFY_TIMEOUT_MS
2958
#define RTW_MESH_ACNODE_NOTIFY_TIMEOUT_MS (2 * 1000)
2959
#endif
2960
2961
#ifndef RTW_MESH_OFFCH_CAND
2962
#define RTW_MESH_OFFCH_CAND 1
2963
#endif
2964
#ifndef RTW_MESH_OFFCH_CAND_FIND_INT_MS
2965
#define RTW_MESH_OFFCH_CAND_FIND_INT_MS (10 * 1000)
2966
#endif
2967
2968
#ifndef RTW_MESH_PEER_CONF_TIMEOUT_MS
2969
#define RTW_MESH_PEER_CONF_TIMEOUT_MS (20 * 1000)
2970
#endif
2971
#ifndef RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS
2972
#define RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS (20 * 1000)
2973
#endif
2974
2975
#ifndef RTW_MESH_CTO_MGATE_REQUIRE
2976
#define RTW_MESH_CTO_MGATE_REQUIRE 0
2977
#endif
2978
#ifndef RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS
2979
#define RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS (20 * 1000)
2980
#endif
2981
#ifndef RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS
2982
#define RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS (20 * 1000)
2983
#endif
2984
2985
void rtw_mesh_cfg_init_peer_sel_policy(struct rtw_mesh_cfg *mcfg)
2986
{
2987
struct mesh_peer_sel_policy *sel_policy = &mcfg->peer_sel_policy;
2988
2989
sel_policy->scanr_exp_ms = RTW_MESH_SCAN_RESULT_EXP_MS;
2990
2991
#if CONFIG_RTW_MESH_ACNODE_PREVENT
2992
sel_policy->acnode_prevent = RTW_MESH_ACNODE_PREVENT;
2993
sel_policy->acnode_conf_timeout_ms = RTW_MESH_ACNODE_CONF_TIMEOUT_MS;
2994
sel_policy->acnode_notify_timeout_ms = RTW_MESH_ACNODE_NOTIFY_TIMEOUT_MS;
2995
#endif
2996
2997
#if CONFIG_RTW_MESH_OFFCH_CAND
2998
sel_policy->offch_cand = RTW_MESH_OFFCH_CAND;
2999
sel_policy->offch_find_int_ms = RTW_MESH_OFFCH_CAND_FIND_INT_MS;
3000
#endif
3001
3002
#if CONFIG_RTW_MESH_PEER_BLACKLIST
3003
sel_policy->peer_conf_timeout_ms = RTW_MESH_PEER_CONF_TIMEOUT_MS;
3004
sel_policy->peer_blacklist_timeout_ms = RTW_MESH_PEER_BLACKLIST_TIMEOUT_MS;
3005
#endif
3006
3007
#if CONFIG_RTW_MESH_CTO_MGATE_BLACKLIST
3008
sel_policy->cto_mgate_require = RTW_MESH_CTO_MGATE_REQUIRE;
3009
sel_policy->cto_mgate_conf_timeout_ms = RTW_MESH_CTO_MGATE_CONF_TIMEOUT_MS;
3010
sel_policy->cto_mgate_blacklist_timeout_ms = RTW_MESH_CTO_MGATE_BLACKLIST_TIMEOUT_MS;
3011
#endif
3012
}
3013
3014
void rtw_mesh_cfg_init(_adapter *adapter)
3015
{
3016
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
3017
3018
mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS;
3019
mcfg->plink_timeout = RTW_MESH_PEER_LINK_TIMEOUT;
3020
3021
mcfg->dot11MeshTTL = RTW_MESH_TTL;
3022
mcfg->element_ttl = RTW_MESH_DEFAULT_ELEMENT_TTL;
3023
mcfg->dot11MeshHWMPmaxPREQretries = RTW_MESH_MAX_PREQ_RETRIES;
3024
mcfg->path_refresh_time = RTW_MESH_PATH_REFRESH_TIME;
3025
mcfg->min_discovery_timeout = RTW_MESH_MIN_DISCOVERY_TIMEOUT;
3026
mcfg->dot11MeshHWMPactivePathTimeout = RTW_MESH_PATH_TIMEOUT;
3027
mcfg->dot11MeshHWMPpreqMinInterval = RTW_MESH_PREQ_MIN_INT;
3028
mcfg->dot11MeshHWMPperrMinInterval = RTW_MESH_PERR_MIN_INT;
3029
mcfg->dot11MeshHWMPnetDiameterTraversalTime = RTW_MESH_DIAM_TRAVERSAL_TIME;
3030
mcfg->dot11MeshHWMPRootMode = RTW_IEEE80211_ROOTMODE_NO_ROOT;
3031
mcfg->dot11MeshHWMPRannInterval = RTW_MESH_RANN_INTERVAL;
3032
mcfg->dot11MeshGateAnnouncementProtocol = _FALSE;
3033
mcfg->dot11MeshForwarding = _TRUE;
3034
mcfg->rssi_threshold = 0;
3035
mcfg->dot11MeshHWMPactivePathToRootTimeout = RTW_MESH_PATH_TO_ROOT_TIMEOUT;
3036
mcfg->dot11MeshHWMProotInterval = RTW_MESH_ROOT_INTERVAL;
3037
mcfg->dot11MeshHWMPconfirmationInterval = RTW_MESH_ROOT_CONFIRMATION_INTERVAL;
3038
mcfg->path_gate_timeout_factor = 3;
3039
rtw_mesh_cfg_init_peer_sel_policy(mcfg);
3040
#ifdef CONFIG_RTW_MESH_ADD_ROOT_CHK
3041
mcfg->sane_metric_delta = RTW_MESH_SANE_METRIC_DELTA;
3042
mcfg->max_root_add_chk_cnt = RTW_MESH_MAX_ROOT_ADD_CHK_CNT;
3043
#endif
3044
3045
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3046
mcfg->b2u_flags_msrc = 0;
3047
mcfg->b2u_flags_mfwd = RTW_MESH_B2U_GA_UCAST;
3048
#endif
3049
}
3050
3051
void rtw_mesh_cfg_init_max_peer_links(_adapter *adapter, u8 stack_conf)
3052
{
3053
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
3054
3055
mcfg->max_peer_links = RTW_MESH_MAX_PEER_LINKS;
3056
3057
if (mcfg->max_peer_links > stack_conf)
3058
mcfg->max_peer_links = stack_conf;
3059
}
3060
3061
void rtw_mesh_cfg_init_plink_timeout(_adapter *adapter, u32 stack_conf)
3062
{
3063
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
3064
3065
mcfg->plink_timeout = stack_conf;
3066
}
3067
3068
void rtw_mesh_init_mesh_info(_adapter *adapter)
3069
{
3070
struct rtw_mesh_info *minfo = &adapter->mesh_info;
3071
3072
_rtw_memset(minfo, 0, sizeof(struct rtw_mesh_info));
3073
3074
rtw_mesh_plink_ctl_init(adapter);
3075
3076
minfo->last_preq = rtw_get_current_time();
3077
/* minfo->last_sn_update = rtw_get_current_time(); */
3078
minfo->next_perr = rtw_get_current_time();
3079
3080
ATOMIC_SET(&minfo->mpaths, 0);
3081
rtw_mesh_pathtbl_init(adapter);
3082
3083
_rtw_init_queue(&minfo->mpath_tx_queue);
3084
tasklet_init(&minfo->mpath_tx_tasklet
3085
, (void(*))mpath_tx_tasklet_hdl
3086
, (unsigned long)adapter);
3087
3088
rtw_mrc_init(adapter);
3089
3090
_rtw_init_listhead(&minfo->preq_queue.list);
3091
_rtw_spinlock_init(&minfo->mesh_preq_queue_lock);
3092
3093
rtw_init_timer(&adapter->mesh_path_timer, adapter, rtw_ieee80211_mesh_path_timer, adapter);
3094
rtw_init_timer(&adapter->mesh_path_root_timer, adapter, rtw_ieee80211_mesh_path_root_timer, adapter);
3095
rtw_init_timer(&adapter->mesh_atlm_param_req_timer, adapter, rtw_mesh_atlm_param_req_timer, adapter);
3096
_init_workitem(&adapter->mesh_work, rtw_mesh_work_hdl, NULL);
3097
}
3098
3099
void rtw_mesh_deinit_mesh_info(_adapter *adapter)
3100
{
3101
struct rtw_mesh_info *minfo = &adapter->mesh_info;
3102
3103
tasklet_kill(&minfo->mpath_tx_tasklet);
3104
rtw_mpath_tx_queue_flush(adapter);
3105
_rtw_deinit_queue(&adapter->mesh_info.mpath_tx_queue);
3106
3107
rtw_mrc_free(adapter);
3108
3109
rtw_mesh_pathtbl_unregister(adapter);
3110
3111
rtw_mesh_plink_ctl_deinit(adapter);
3112
3113
_cancel_workitem_sync(&adapter->mesh_work);
3114
_cancel_timer_ex(&adapter->mesh_path_timer);
3115
_cancel_timer_ex(&adapter->mesh_path_root_timer);
3116
_cancel_timer_ex(&adapter->mesh_atlm_param_req_timer);
3117
}
3118
3119
/**
3120
* rtw_mesh_nexthop_resolve - lookup next hop; conditionally start path discovery
3121
*
3122
* @skb: 802.11 frame to be sent
3123
* @sdata: network subif the frame will be sent through
3124
*
3125
* Lookup next hop for given skb and start path discovery if no
3126
* forwarding information is found.
3127
*
3128
* Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
3129
* skb is freeed here if no mpath could be allocated.
3130
*/
3131
int rtw_mesh_nexthop_resolve(_adapter *adapter,
3132
struct xmit_frame *xframe)
3133
{
3134
struct pkt_attrib *attrib = &xframe->attrib;
3135
struct rtw_mesh_path *mpath;
3136
struct xmit_frame *xframe_to_free = NULL;
3137
u8 *target_addr = attrib->mda;
3138
int err = 0;
3139
int ret = _SUCCESS;
3140
3141
rtw_rcu_read_lock();
3142
err = rtw_mesh_nexthop_lookup(adapter, target_addr, attrib->msa, attrib->ra);
3143
if (!err)
3144
goto endlookup;
3145
3146
/* no nexthop found, start resolving */
3147
mpath = rtw_mesh_path_lookup(adapter, target_addr);
3148
if (!mpath) {
3149
mpath = rtw_mesh_path_add(adapter, target_addr);
3150
if (IS_ERR(mpath)) {
3151
xframe->pkt = NULL; /* free pkt outside */
3152
rtw_mesh_path_discard_frame(adapter, xframe);
3153
err = PTR_ERR(mpath);
3154
ret = _FAIL;
3155
goto endlookup;
3156
}
3157
}
3158
3159
if (!(mpath->flags & RTW_MESH_PATH_RESOLVING))
3160
rtw_mesh_queue_preq(mpath, RTW_PREQ_Q_F_START);
3161
3162
enter_critical_bh(&mpath->frame_queue.lock);
3163
3164
if (mpath->frame_queue_len >= RTW_MESH_FRAME_QUEUE_LEN) {
3165
xframe_to_free = LIST_CONTAINOR(get_next(get_list_head(&mpath->frame_queue)), struct xmit_frame, list);
3166
rtw_list_delete(&(xframe_to_free->list));
3167
mpath->frame_queue_len--;
3168
}
3169
3170
rtw_list_insert_tail(&xframe->list, get_list_head(&mpath->frame_queue));
3171
mpath->frame_queue_len++;
3172
3173
exit_critical_bh(&mpath->frame_queue.lock);
3174
3175
ret = RTW_RA_RESOLVING;
3176
if (xframe_to_free)
3177
rtw_mesh_path_discard_frame(adapter, xframe_to_free);
3178
3179
endlookup:
3180
rtw_rcu_read_unlock();
3181
return ret;
3182
}
3183
3184
/**
3185
* rtw_mesh_nexthop_lookup - put the appropriate next hop on a mesh frame. Calling
3186
* this function is considered "using" the associated mpath, so preempt a path
3187
* refresh if this mpath expires soon.
3188
*
3189
* @skb: 802.11 frame to be sent
3190
* @sdata: network subif the frame will be sent through
3191
*
3192
* Returns: 0 if the next hop was found. Nonzero otherwise.
3193
*/
3194
int rtw_mesh_nexthop_lookup(_adapter *adapter,
3195
const u8 *mda, const u8 *msa, u8 *ra)
3196
{
3197
struct rtw_mesh_path *mpath;
3198
struct sta_info *next_hop;
3199
const u8 *target_addr = mda;
3200
int err = -ENOENT;
3201
struct registry_priv *registry_par = &adapter->registrypriv;
3202
u8 peer_alive_based_preq = registry_par->peer_alive_based_preq;
3203
BOOLEAN nexthop_alive = _TRUE;
3204
3205
rtw_rcu_read_lock();
3206
mpath = rtw_mesh_path_lookup(adapter, target_addr);
3207
3208
if (!mpath || !(mpath->flags & RTW_MESH_PATH_ACTIVE))
3209
goto endlookup;
3210
3211
next_hop = rtw_rcu_dereference(mpath->next_hop);
3212
if (next_hop) {
3213
_rtw_memcpy(ra, next_hop->cmn.mac_addr, ETH_ALEN);
3214
err = 0;
3215
}
3216
3217
if (peer_alive_based_preq && next_hop)
3218
nexthop_alive = next_hop->alive;
3219
3220
if (_rtw_memcmp(adapter_mac_addr(adapter), msa, ETH_ALEN) == _TRUE &&
3221
!(mpath->flags & RTW_MESH_PATH_RESOLVING) &&
3222
!(mpath->flags & RTW_MESH_PATH_FIXED)) {
3223
u8 flags = RTW_PREQ_Q_F_START | RTW_PREQ_Q_F_REFRESH;
3224
3225
if (peer_alive_based_preq && nexthop_alive == _FALSE) {
3226
flags |= RTW_PREQ_Q_F_BCAST_PREQ;
3227
rtw_mesh_queue_preq(mpath, flags);
3228
} else if (rtw_time_after(rtw_get_current_time(),
3229
mpath->exp_time -
3230
rtw_ms_to_systime(adapter->mesh_cfg.path_refresh_time))) {
3231
rtw_mesh_queue_preq(mpath, flags);
3232
}
3233
/* Avoid keeping trying unicast PREQ toward root,
3234
when next_hop leaves */
3235
} else if (peer_alive_based_preq &&
3236
_rtw_memcmp(adapter_mac_addr(adapter), msa, ETH_ALEN) == _TRUE &&
3237
(mpath->flags & RTW_MESH_PATH_RESOLVING) &&
3238
!(mpath->flags & RTW_MESH_PATH_FIXED) &&
3239
!(mpath->flags & RTW_MESH_PATH_BCAST_PREQ) &&
3240
mpath->is_root && nexthop_alive == _FALSE) {
3241
enter_critical_bh(&mpath->state_lock);
3242
mpath->flags |= RTW_MESH_PATH_BCAST_PREQ;
3243
exit_critical_bh(&mpath->state_lock);
3244
}
3245
3246
endlookup:
3247
rtw_rcu_read_unlock();
3248
return err;
3249
}
3250
3251
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3252
static bool rtw_mesh_data_bmc_to_uc(_adapter *adapter
3253
, const u8 *da, const u8 *sa, const u8 *mda, const u8 *msa
3254
, u8 ae_need, const u8 *ori_ta, u8 mfwd_ttl
3255
, _list *b2u_list, u8 *b2u_num, u32 *b2u_mseq)
3256
{
3257
struct sta_priv *stapriv = &adapter->stapriv;
3258
struct xmit_priv *xmitpriv = &adapter->xmitpriv;
3259
_irqL irqL;
3260
_list *head, *list;
3261
struct sta_info *sta;
3262
char b2u_sta_id[NUM_STA];
3263
u8 b2u_sta_num = 0;
3264
bool bmc_need = _FALSE;
3265
int i;
3266
3267
_enter_critical_bh(&stapriv->asoc_list_lock, &irqL);
3268
head = &stapriv->asoc_list;
3269
list = get_next(head);
3270
3271
while ((rtw_end_of_queue_search(head, list)) == _FALSE) {
3272
int stainfo_offset;
3273
3274
sta = LIST_CONTAINOR(list, struct sta_info, asoc_list);
3275
list = get_next(list);
3276
3277
stainfo_offset = rtw_stainfo_offset(stapriv, sta);
3278
if (stainfo_offset_valid(stainfo_offset))
3279
b2u_sta_id[b2u_sta_num++] = stainfo_offset;
3280
}
3281
_exit_critical_bh(&stapriv->asoc_list_lock, &irqL);
3282
3283
if (!b2u_sta_num)
3284
goto exit;
3285
3286
for (i = 0; i < b2u_sta_num; i++) {
3287
struct xmit_frame *b2uframe;
3288
struct pkt_attrib *attrib;
3289
3290
sta = rtw_get_stainfo_by_offset(stapriv, b2u_sta_id[i]);
3291
if (!(sta->state & _FW_LINKED)
3292
|| _rtw_memcmp(sta->cmn.mac_addr, msa, ETH_ALEN) == _TRUE
3293
|| (ori_ta && _rtw_memcmp(sta->cmn.mac_addr, ori_ta, ETH_ALEN) == _TRUE)
3294
|| is_broadcast_mac_addr(sta->cmn.mac_addr)
3295
|| is_zero_mac_addr(sta->cmn.mac_addr))
3296
continue;
3297
3298
b2uframe = rtw_alloc_xmitframe(xmitpriv);
3299
if (!b2uframe) {
3300
bmc_need = _TRUE;
3301
break;
3302
}
3303
3304
if ((*b2u_num)++ == 0 && !ori_ta) {
3305
*b2u_mseq = (cpu_to_le32(adapter->mesh_info.mesh_seqnum));
3306
adapter->mesh_info.mesh_seqnum++;
3307
}
3308
3309
attrib = &b2uframe->attrib;
3310
3311
attrib->mb2u = 1;
3312
attrib->mseq = *b2u_mseq;
3313
attrib->mfwd_ttl = ori_ta ? mfwd_ttl : 0;
3314
_rtw_memcpy(attrib->ra, sta->cmn.mac_addr, ETH_ALEN);
3315
_rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN);
3316
_rtw_memcpy(attrib->mda, mda, ETH_ALEN);
3317
_rtw_memcpy(attrib->msa, msa, ETH_ALEN);
3318
_rtw_memcpy(attrib->dst, da, ETH_ALEN);
3319
_rtw_memcpy(attrib->src, sa, ETH_ALEN);
3320
attrib->mesh_frame_mode = ae_need ? MESH_UCAST_PX_DATA : MESH_UCAST_DATA;
3321
3322
rtw_list_insert_tail(&b2uframe->list, b2u_list);
3323
}
3324
3325
exit:
3326
return bmc_need;
3327
}
3328
3329
void dump_mesh_b2u_flags(void *sel, _adapter *adapter)
3330
{
3331
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
3332
3333
RTW_PRINT_SEL(sel, "%4s %4s\n", "msrc", "mfwd");
3334
RTW_PRINT_SEL(sel, "0x%02x 0x%02x\n", mcfg->b2u_flags_msrc, mcfg->b2u_flags_mfwd);
3335
}
3336
#endif /* CONFIG_RTW_MESH_DATA_BMC_TO_UC */
3337
3338
int rtw_mesh_addr_resolve(_adapter *adapter, struct xmit_frame *xframe, _pkt *pkt, _list *b2u_list)
3339
{
3340
struct pkt_file pktfile;
3341
struct ethhdr etherhdr;
3342
struct pkt_attrib *attrib;
3343
struct rtw_mesh_path *mpath = NULL, *mppath = NULL;
3344
u8 is_da_mcast;
3345
u8 ae_need;
3346
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3347
bool bmc_need = _TRUE;
3348
u8 b2u_num = 0;
3349
u32 b2u_mseq = 0;
3350
#endif
3351
int res = _SUCCESS;
3352
3353
_rtw_open_pktfile(pkt, &pktfile);
3354
if (_rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN) != ETH_HLEN) {
3355
res = _FAIL;
3356
goto exit;
3357
}
3358
3359
xframe->pkt = pkt;
3360
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3361
_rtw_init_listhead(b2u_list);
3362
#endif
3363
3364
is_da_mcast = IS_MCAST(etherhdr.h_dest);
3365
if (!is_da_mcast) {
3366
struct sta_info *next_hop;
3367
bool mpp_lookup = 1;
3368
3369
mpath = rtw_mesh_path_lookup(adapter, etherhdr.h_dest);
3370
if (mpath) {
3371
mpp_lookup = 0;
3372
next_hop = rtw_rcu_dereference(mpath->next_hop);
3373
if (!next_hop
3374
|| !(mpath->flags & (RTW_MESH_PATH_ACTIVE | RTW_MESH_PATH_RESOLVING))
3375
) {
3376
/* mpath is not valid, search mppath */
3377
mpp_lookup = 1;
3378
}
3379
}
3380
3381
if (mpp_lookup) {
3382
mppath = rtw_mpp_path_lookup(adapter, etherhdr.h_dest);
3383
if (mppath)
3384
mppath->exp_time = rtw_get_current_time();
3385
}
3386
3387
if (mppath && mpath)
3388
rtw_mesh_path_del(adapter, mpath->dst);
3389
3390
ae_need = _rtw_memcmp(adapter_mac_addr(adapter), etherhdr.h_source, ETH_ALEN) == _FALSE
3391
|| (mppath && _rtw_memcmp(mppath->mpp, etherhdr.h_dest, ETH_ALEN) == _FALSE);
3392
} else {
3393
ae_need = _rtw_memcmp(adapter_mac_addr(adapter), etherhdr.h_source, ETH_ALEN) == _FALSE;
3394
3395
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3396
if (rtw_msrc_b2u_policy_chk(adapter->mesh_cfg.b2u_flags_msrc, etherhdr.h_dest)) {
3397
bmc_need = rtw_mesh_data_bmc_to_uc(adapter
3398
, etherhdr.h_dest, etherhdr.h_source
3399
, etherhdr.h_dest, adapter_mac_addr(adapter), ae_need, NULL, 0
3400
, b2u_list, &b2u_num, &b2u_mseq);
3401
if (bmc_need == _FALSE) {
3402
res = RTW_BMC_NO_NEED;
3403
goto exit;
3404
}
3405
}
3406
#endif
3407
}
3408
3409
attrib = &xframe->attrib;
3410
3411
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3412
if (b2u_num) {
3413
attrib->mb2u = 1;
3414
attrib->mseq = b2u_mseq;
3415
} else
3416
attrib->mb2u = 0;
3417
#endif
3418
3419
attrib->mfwd_ttl = 0;
3420
_rtw_memcpy(attrib->dst, etherhdr.h_dest, ETH_ALEN);
3421
_rtw_memcpy(attrib->src, etherhdr.h_source, ETH_ALEN);
3422
_rtw_memcpy(attrib->ta, adapter_mac_addr(adapter), ETH_ALEN);
3423
3424
if (is_da_mcast) {
3425
attrib->mesh_frame_mode = ae_need ? MESH_BMCAST_PX_DATA : MESH_BMCAST_DATA;
3426
_rtw_memcpy(attrib->ra, attrib->dst, ETH_ALEN);
3427
_rtw_memcpy(attrib->msa, adapter_mac_addr(adapter), ETH_ALEN);
3428
} else {
3429
attrib->mesh_frame_mode = ae_need ? MESH_UCAST_PX_DATA : MESH_UCAST_DATA;
3430
_rtw_memcpy(attrib->mda, (mppath && ae_need) ? mppath->mpp : attrib->dst, ETH_ALEN);
3431
_rtw_memcpy(attrib->msa, adapter_mac_addr(adapter), ETH_ALEN);
3432
/* RA needs to be resolved */
3433
res = rtw_mesh_nexthop_resolve(adapter, xframe);
3434
}
3435
3436
exit:
3437
return res;
3438
}
3439
3440
s8 rtw_mesh_tx_set_whdr_mctrl_len(u8 mesh_frame_mode, struct pkt_attrib *attrib)
3441
{
3442
u8 ret = 0;
3443
switch (mesh_frame_mode) {
3444
case MESH_UCAST_DATA:
3445
attrib->hdrlen = WLAN_HDR_A4_QOS_LEN;
3446
/* mesh flag + mesh TTL + Mesh SN. no ext addr. */
3447
attrib->meshctrl_len = 6;
3448
break;
3449
case MESH_BMCAST_DATA:
3450
attrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
3451
/* mesh flag + mesh TTL + Mesh SN. no ext addr. */
3452
attrib->meshctrl_len = 6;
3453
break;
3454
case MESH_UCAST_PX_DATA:
3455
attrib->hdrlen = WLAN_HDR_A4_QOS_LEN;
3456
/* mesh flag + mesh TTL + Mesh SN + extaddr1 + extaddr2. */
3457
attrib->meshctrl_len = 18;
3458
break;
3459
case MESH_BMCAST_PX_DATA:
3460
attrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
3461
/* mesh flag + mesh TTL + Mesh SN + extaddr1 */
3462
attrib->meshctrl_len = 12;
3463
break;
3464
default:
3465
RTW_WARN("Invalid mesh frame mode:%u\n", mesh_frame_mode);
3466
ret = -1;
3467
break;
3468
}
3469
3470
return ret;
3471
}
3472
3473
void rtw_mesh_tx_build_mctrl(_adapter *adapter, struct pkt_attrib *attrib, u8 *buf)
3474
{
3475
struct rtw_ieee80211s_hdr *mctrl = (struct rtw_ieee80211s_hdr *)buf;
3476
3477
_rtw_memset(mctrl, 0, XATTRIB_GET_MCTRL_LEN(attrib));
3478
3479
if (attrib->mfwd_ttl
3480
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3481
|| attrib->mb2u
3482
#endif
3483
) {
3484
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3485
if (!attrib->mfwd_ttl)
3486
mctrl->ttl = adapter->mesh_cfg.dot11MeshTTL;
3487
else
3488
#endif
3489
mctrl->ttl = attrib->mfwd_ttl;
3490
3491
mctrl->seqnum = (cpu_to_le32(attrib->mseq));
3492
} else {
3493
mctrl->ttl = adapter->mesh_cfg.dot11MeshTTL;
3494
mctrl->seqnum = (cpu_to_le32(adapter->mesh_info.mesh_seqnum));
3495
adapter->mesh_info.mesh_seqnum++;
3496
}
3497
3498
switch (attrib->mesh_frame_mode){
3499
case MESH_UCAST_DATA:
3500
case MESH_BMCAST_DATA:
3501
break;
3502
case MESH_UCAST_PX_DATA:
3503
mctrl->flags |= MESH_FLAGS_AE_A5_A6;
3504
_rtw_memcpy(mctrl->eaddr1, attrib->dst, ETH_ALEN);
3505
_rtw_memcpy(mctrl->eaddr2, attrib->src, ETH_ALEN);
3506
break;
3507
case MESH_BMCAST_PX_DATA:
3508
mctrl->flags |= MESH_FLAGS_AE_A4;
3509
_rtw_memcpy(mctrl->eaddr1, attrib->src, ETH_ALEN);
3510
break;
3511
case MESH_MHOP_UCAST_ACT:
3512
/* TBD */
3513
break;
3514
case MESH_MHOP_BMCAST_ACT:
3515
/* TBD */
3516
break;
3517
default:
3518
break;
3519
}
3520
}
3521
3522
u8 rtw_mesh_tx_build_whdr(_adapter *adapter, struct pkt_attrib *attrib
3523
, u16 *fctrl, struct rtw_ieee80211_hdr *whdr)
3524
{
3525
switch (attrib->mesh_frame_mode) {
3526
case MESH_UCAST_DATA: /* 1, 1, RA, TA, mDA(=DA), mSA(=SA) */
3527
case MESH_UCAST_PX_DATA: /* 1, 1, RA, TA, mDA, mSA, [DA, SA] */
3528
SetToDs(fctrl);
3529
SetFrDs(fctrl);
3530
_rtw_memcpy(whdr->addr1, attrib->ra, ETH_ALEN);
3531
_rtw_memcpy(whdr->addr2, attrib->ta, ETH_ALEN);
3532
_rtw_memcpy(whdr->addr3, attrib->mda, ETH_ALEN);
3533
_rtw_memcpy(whdr->addr4, attrib->msa, ETH_ALEN);
3534
break;
3535
case MESH_BMCAST_DATA: /* 0, 1, RA(DA), TA, mSA(SA) */
3536
case MESH_BMCAST_PX_DATA: /* 0, 1, RA(DA), TA, mSA, [SA] */
3537
SetFrDs(fctrl);
3538
_rtw_memcpy(whdr->addr1, attrib->ra, ETH_ALEN);
3539
_rtw_memcpy(whdr->addr2, attrib->ta, ETH_ALEN);
3540
_rtw_memcpy(whdr->addr3, attrib->msa, ETH_ALEN);
3541
break;
3542
case MESH_MHOP_UCAST_ACT:
3543
/* TBD */
3544
RTW_INFO("MESH_MHOP_UCAST_ACT\n");
3545
break;
3546
case MESH_MHOP_BMCAST_ACT:
3547
/* TBD */
3548
RTW_INFO("MESH_MHOP_BMCAST_ACT\n");
3549
break;
3550
default:
3551
RTW_WARN("Invalid mesh frame mode\n");
3552
break;
3553
}
3554
3555
return 0;
3556
}
3557
3558
int rtw_mesh_rx_data_validate_hdr(_adapter *adapter, union recv_frame *rframe, struct sta_info **sta)
3559
{
3560
struct sta_priv *stapriv = &adapter->stapriv;
3561
struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
3562
u8 *whdr = get_recvframe_data(rframe);
3563
u8 is_ra_bmc = 0;
3564
u8 a4_shift = 0;
3565
u8 ps;
3566
u8 *qc;
3567
u8 mps_mode = RTW_MESH_PS_UNKNOWN;
3568
sint ret = _FAIL;
3569
3570
if (!(MLME_STATE(adapter) & WIFI_ASOC_STATE))
3571
goto exit;
3572
3573
if (!rattrib->qos)
3574
goto exit;
3575
3576
switch (rattrib->to_fr_ds) {
3577
case 1:
3578
if (!IS_MCAST(GetAddr1Ptr(whdr)))
3579
goto exit;
3580
*sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr));
3581
if (*sta == NULL) {
3582
ret = _SUCCESS; /* return _SUCCESS to drop at sta checking */
3583
goto exit;
3584
}
3585
_rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN);
3586
_rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN);
3587
_rtw_memcpy(rattrib->mda, GetAddr1Ptr(whdr), ETH_ALEN);
3588
_rtw_memcpy(rattrib->msa, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */
3589
_rtw_memcpy(rattrib->dst, GetAddr1Ptr(whdr), ETH_ALEN);
3590
_rtw_memcpy(rattrib->src, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking mesh ctrl field */
3591
_rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN);
3592
is_ra_bmc = 1;
3593
break;
3594
case 3:
3595
if (IS_MCAST(GetAddr1Ptr(whdr)))
3596
goto exit;
3597
*sta = rtw_get_stainfo(stapriv, get_addr2_ptr(whdr));
3598
if (*sta == NULL) {
3599
ret = _SUCCESS; /* return _SUCCESS to drop at sta checking */
3600
goto exit;
3601
}
3602
_rtw_memcpy(rattrib->ra, GetAddr1Ptr(whdr), ETH_ALEN);
3603
_rtw_memcpy(rattrib->ta, get_addr2_ptr(whdr), ETH_ALEN);
3604
_rtw_memcpy(rattrib->mda, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */
3605
_rtw_memcpy(rattrib->msa, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking AMSDU subframe header */
3606
_rtw_memcpy(rattrib->dst, GetAddr3Ptr(whdr), ETH_ALEN); /* may change after checking mesh ctrl field */
3607
_rtw_memcpy(rattrib->src, GetAddr4Ptr(whdr), ETH_ALEN); /* may change after checking mesh ctrl field */
3608
_rtw_memcpy(rattrib->bssid, get_addr2_ptr(whdr), ETH_ALEN);
3609
a4_shift = ETH_ALEN;
3610
break;
3611
default:
3612
goto exit;
3613
}
3614
3615
qc = whdr + WLAN_HDR_A3_LEN + a4_shift;
3616
ps = GetPwrMgt(whdr);
3617
mps_mode = ps ? (is_ra_bmc || (get_mps_lv(qc)) ? RTW_MESH_PS_DSLEEP : RTW_MESH_PS_LSLEEP) : RTW_MESH_PS_ACTIVE;
3618
3619
if (ps) {
3620
if (!((*sta)->state & WIFI_SLEEP_STATE))
3621
stop_sta_xmit(adapter, *sta);
3622
} else {
3623
if ((*sta)->state & WIFI_SLEEP_STATE)
3624
wakeup_sta_to_xmit(adapter, *sta);
3625
}
3626
3627
if (is_ra_bmc)
3628
(*sta)->nonpeer_mps = mps_mode;
3629
else {
3630
(*sta)->peer_mps = mps_mode;
3631
if (mps_mode != RTW_MESH_PS_ACTIVE && (*sta)->nonpeer_mps == RTW_MESH_PS_ACTIVE)
3632
(*sta)->nonpeer_mps = RTW_MESH_PS_DSLEEP;
3633
}
3634
3635
if (get_frame_sub_type(whdr) & BIT(6)) {
3636
/* No data, will not indicate to upper layer, temporily count it here */
3637
count_rx_stats(adapter, rframe, *sta);
3638
ret = RTW_RX_HANDLED;
3639
goto exit;
3640
}
3641
3642
rattrib->mesh_ctrl_present = get_mctrl_present(qc) ? 1 : 0;
3643
if (!rattrib->mesh_ctrl_present)
3644
goto exit;
3645
3646
ret = _SUCCESS;
3647
3648
exit:
3649
return ret;
3650
}
3651
3652
int rtw_mesh_rx_data_validate_mctrl(_adapter *adapter, union recv_frame *rframe
3653
, const struct rtw_ieee80211s_hdr *mctrl, const u8 *mda, const u8 *msa
3654
, u8 *mctrl_len
3655
, const u8 **da, const u8 **sa)
3656
{
3657
struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
3658
u8 mlen;
3659
u8 ae;
3660
int ret = _SUCCESS;
3661
3662
ae = mctrl->flags & MESH_FLAGS_AE;
3663
mlen = ae_to_mesh_ctrl_len[ae];
3664
switch (rattrib->to_fr_ds) {
3665
case 1:
3666
*da = mda;
3667
if (ae == MESH_FLAGS_AE_A4)
3668
*sa = mctrl->eaddr1;
3669
else if (ae == 0)
3670
*sa = msa;
3671
else
3672
ret = _FAIL;
3673
break;
3674
case 3:
3675
if (ae == MESH_FLAGS_AE_A5_A6) {
3676
*da = mctrl->eaddr1;
3677
*sa = mctrl->eaddr2;
3678
} else if (ae == 0) {
3679
*da = mda;
3680
*sa = msa;
3681
} else
3682
ret = _FAIL;
3683
break;
3684
default:
3685
ret = _FAIL;
3686
}
3687
3688
if (ret == _FAIL) {
3689
#ifdef DBG_RX_DROP_FRAME
3690
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" invalid tfDS:%u AE:%u combination ra="MAC_FMT" ta="MAC_FMT"\n"
3691
, FUNC_ADPT_ARG(adapter), rattrib->to_fr_ds, ae, MAC_ARG(rattrib->ra), MAC_ARG(rattrib->ta));
3692
#endif
3693
*mctrl_len = 0;
3694
} else
3695
*mctrl_len = mlen;
3696
3697
return ret;
3698
}
3699
3700
inline int rtw_mesh_rx_validate_mctrl_non_amsdu(_adapter *adapter, union recv_frame *rframe)
3701
{
3702
struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
3703
const u8 *da, *sa;
3704
int ret;
3705
3706
ret = rtw_mesh_rx_data_validate_mctrl(adapter, rframe
3707
, (struct rtw_ieee80211s_hdr *)(get_recvframe_data(rframe) + rattrib->hdrlen + rattrib->iv_len)
3708
, rattrib->mda, rattrib->msa
3709
, &rattrib->mesh_ctrl_len
3710
, &da, &sa);
3711
3712
if (ret == _SUCCESS) {
3713
_rtw_memcpy(rattrib->dst, da, ETH_ALEN);
3714
_rtw_memcpy(rattrib->src, sa, ETH_ALEN);
3715
}
3716
3717
return ret;
3718
}
3719
3720
/**
3721
* rtw_mesh_rx_nexthop_resolve - lookup next hop; conditionally start path discovery
3722
*
3723
* @skb: 802.11 frame to be sent
3724
* @sdata: network subif the frame will be sent through
3725
*
3726
* Lookup next hop for given skb and start path discovery if no
3727
* forwarding information is found.
3728
*
3729
* Returns: 0 if the next hop was found and -ENOENT if the frame was queued.
3730
* skb is freeed here if no mpath could be allocated.
3731
*/
3732
static int rtw_mesh_rx_nexthop_resolve(_adapter *adapter,
3733
const u8 *mda, const u8 *msa, u8 *ra)
3734
{
3735
struct rtw_mesh_path *mpath;
3736
struct xmit_frame *xframe_to_free = NULL;
3737
int err = 0;
3738
int ret = _SUCCESS;
3739
3740
rtw_rcu_read_lock();
3741
err = rtw_mesh_nexthop_lookup(adapter, mda, msa, ra);
3742
if (!err)
3743
goto endlookup;
3744
3745
/* no nexthop found, start resolving */
3746
mpath = rtw_mesh_path_lookup(adapter, mda);
3747
if (!mpath) {
3748
mpath = rtw_mesh_path_add(adapter, mda);
3749
if (IS_ERR(mpath)) {
3750
err = PTR_ERR(mpath);
3751
ret = _FAIL;
3752
goto endlookup;
3753
}
3754
}
3755
3756
if (!(mpath->flags & RTW_MESH_PATH_RESOLVING))
3757
rtw_mesh_queue_preq(mpath, RTW_PREQ_Q_F_START);
3758
3759
ret = _FAIL;
3760
3761
endlookup:
3762
rtw_rcu_read_unlock();
3763
return ret;
3764
}
3765
3766
#define RTW_MESH_DECACHE_BMC 1
3767
#define RTW_MESH_DECACHE_UC 0
3768
3769
#define RTW_MESH_FORWARD_MDA_SELF_COND 0
3770
#define DBG_RTW_MESH_FORWARD_MDA_SELF_COND 0
3771
int rtw_mesh_rx_msdu_act_check(union recv_frame *rframe
3772
, const u8 *mda, const u8 *msa
3773
, const u8 *da, const u8 *sa
3774
, struct rtw_ieee80211s_hdr *mctrl
3775
, struct xmit_frame **fwd_frame, _list *b2u_list)
3776
{
3777
_adapter *adapter = rframe->u.hdr.adapter;
3778
struct rtw_mesh_cfg *mcfg = &adapter->mesh_cfg;
3779
struct rtw_mesh_info *minfo = &adapter->mesh_info;
3780
struct rx_pkt_attrib *rattrib = &rframe->u.hdr.attrib;
3781
struct rtw_mesh_path *mppath;
3782
u8 is_mda_bmc = IS_MCAST(mda);
3783
u8 is_mda_self = !is_mda_bmc && _rtw_memcmp(mda, adapter_mac_addr(adapter), ETH_ALEN);
3784
struct xmit_frame *xframe;
3785
struct pkt_attrib *xattrib;
3786
u8 fwd_ra[ETH_ALEN] = {0};
3787
u8 fwd_mpp[ETH_ALEN] = {0}; /* forward to other gate */
3788
u32 fwd_mseq;
3789
int act = 0;
3790
u8 ae_need;
3791
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
3792
bool bmc_need = _TRUE;
3793
u8 b2u_num = 0;
3794
#endif
3795
3796
/* fwd info lifetime update */
3797
#if 0
3798
if (!is_mda_self)
3799
mDA(A3) fwinfo.lifetime
3800
mSA(A4) fwinfo.lifetime
3801
Precursor-to-mDA(A2) fwinfo.lifetime
3802
#endif
3803
3804
/* update/create pxoxy info for SA, mSA */
3805
if ((mctrl->flags & MESH_FLAGS_AE)
3806
&& sa != msa && _rtw_memcmp(sa, msa, ETH_ALEN) == _FALSE
3807
) {
3808
const u8 *proxied_addr = sa;
3809
const u8 *mpp_addr = msa;
3810
3811
rtw_rcu_read_lock();
3812
mppath = rtw_mpp_path_lookup(adapter, proxied_addr);
3813
if (!mppath)
3814
rtw_mpp_path_add(adapter, proxied_addr, mpp_addr);
3815
else {
3816
enter_critical_bh(&mppath->state_lock);
3817
if (_rtw_memcmp(mppath->mpp, mpp_addr, ETH_ALEN) == _FALSE)
3818
_rtw_memcpy(mppath->mpp, mpp_addr, ETH_ALEN);
3819
mppath->exp_time = rtw_get_current_time();
3820
exit_critical_bh(&mppath->state_lock);
3821
}
3822
rtw_rcu_read_unlock();
3823
}
3824
3825
/* mSA is self, need no further process */
3826
if (_rtw_memcmp(msa, adapter_mac_addr(adapter), ETH_ALEN) == _TRUE)
3827
goto exit;
3828
3829
fwd_mseq = le32_to_cpu(mctrl->seqnum);
3830
3831
/* check duplicate MSDU from mSA */
3832
if (((RTW_MESH_DECACHE_BMC && is_mda_bmc)
3833
|| (RTW_MESH_DECACHE_UC && !is_mda_bmc))
3834
&& rtw_mesh_decache(adapter, msa, fwd_mseq)
3835
) {
3836
minfo->mshstats.dropped_frames_duplicate++;
3837
goto exit;
3838
}
3839
3840
if (is_mda_bmc) {
3841
/* mDA is bmc addr */
3842
act |= RTW_RX_MSDU_ACT_INDICATE;
3843
if (!mcfg->dot11MeshForwarding)
3844
goto exit;
3845
goto fwd_chk;
3846
3847
} else if (!is_mda_self) {
3848
/* mDA is unicast but not self */
3849
if (!mcfg->dot11MeshForwarding) {
3850
rtw_mesh_path_error_tx(adapter
3851
, adapter->mesh_cfg.element_ttl
3852
, mda, 0
3853
, WLAN_REASON_MESH_PATH_NOFORWARD
3854
, rattrib->ta
3855
);
3856
#ifdef DBG_RX_DROP_FRAME
3857
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" mDA("MAC_FMT") not self, !dot11MeshForwarding\n"
3858
, FUNC_ADPT_ARG(adapter), MAC_ARG(mda));
3859
#endif
3860
goto exit;
3861
}
3862
3863
if (rtw_mesh_rx_nexthop_resolve(adapter, mda, msa, fwd_ra) != _SUCCESS) {
3864
/* mDA is unknown */
3865
rtw_mesh_path_error_tx(adapter
3866
, adapter->mesh_cfg.element_ttl
3867
, mda, 0
3868
, WLAN_REASON_MESH_PATH_NOFORWARD
3869
, rattrib->ta
3870
);
3871
#ifdef DBG_RX_DROP_FRAME
3872
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" mDA("MAC_FMT") unknown\n"
3873
, FUNC_ADPT_ARG(adapter), MAC_ARG(mda));
3874
#endif
3875
minfo->mshstats.dropped_frames_no_route++;
3876
goto exit;
3877
3878
} else {
3879
/* mDA is known in fwd info */
3880
#if 0
3881
if (TA is not in precursors)
3882
goto exit;
3883
#endif
3884
goto fwd_chk;
3885
}
3886
3887
} else {
3888
/* mDA is self */
3889
#if RTW_MESH_FORWARD_MDA_SELF_COND
3890
if (da == mda
3891
|| _rtw_memcmp(da, adapter_mac_addr(adapter), ETH_ALEN)
3892
) {
3893
/* DA is self, indicate */
3894
act |= RTW_RX_MSDU_ACT_INDICATE;
3895
goto exit;
3896
}
3897
3898
if (rtw_get_iface_by_macddr(adapter, da)) {
3899
/* DA is buddy, indicate */
3900
act |= RTW_RX_MSDU_ACT_INDICATE;
3901
#if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3902
RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") is buddy("ADPT_FMT")\n"
3903
, FUNC_ADPT_ARG(adapter), MAC_ARG(da), ADPT_ARG(rtw_get_iface_by_macddr(adapter, da)));
3904
#endif
3905
goto exit;
3906
}
3907
3908
/* DA is not self or buddy */
3909
if (rtw_mesh_nexthop_lookup(adapter, da, msa, fwd_ra) == 0) {
3910
/* DA is known in fwd info */
3911
if (!mcfg->dot11MeshForwarding) {
3912
/* path error to? */
3913
#if defined(DBG_RX_DROP_FRAME) || DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3914
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") not self, !dot11MeshForwarding\n"
3915
, FUNC_ADPT_ARG(adapter), MAC_ARG(da));
3916
#endif
3917
goto exit;
3918
}
3919
mda = da;
3920
#if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3921
RTW_INFO(FUNC_ADPT_FMT" fwd to DA("MAC_FMT"), fwd_RA("MAC_FMT")\n"
3922
, FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(fwd_ra));
3923
#endif
3924
goto fwd_chk;
3925
}
3926
3927
rtw_rcu_read_lock();
3928
mppath = rtw_mpp_path_lookup(adapter, da);
3929
if (mppath) {
3930
if (_rtw_memcmp(mppath->mpp, adapter_mac_addr(adapter), ETH_ALEN) == _FALSE) {
3931
/* DA is proxied by others */
3932
if (!mcfg->dot11MeshForwarding) {
3933
/* path error to? */
3934
#if defined(DBG_RX_DROP_FRAME) || DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3935
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by ("MAC_FMT"), !dot11MeshForwarding\n"
3936
, FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(mppath->mpp));
3937
#endif
3938
rtw_rcu_read_unlock();
3939
goto exit;
3940
}
3941
_rtw_memcpy(fwd_mpp, mppath->mpp, ETH_ALEN);
3942
mda = fwd_mpp;
3943
msa = adapter_mac_addr(adapter);
3944
rtw_rcu_read_unlock();
3945
3946
/* resolve RA */
3947
if (rtw_mesh_nexthop_lookup(adapter, mda, msa, fwd_ra) != 0) {
3948
minfo->mshstats.dropped_frames_no_route++;
3949
#if defined(DBG_RX_DROP_FRAME) || DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3950
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by ("MAC_FMT"), RA resolve fail\n"
3951
, FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(mppath->mpp));
3952
#endif
3953
goto exit;
3954
}
3955
#if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3956
RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by ("MAC_FMT"), fwd_RA("MAC_FMT")\n"
3957
, FUNC_ADPT_ARG(adapter), MAC_ARG(da), MAC_ARG(mppath->mpp), MAC_ARG(fwd_ra));
3958
#endif
3959
goto fwd_chk; /* forward to other gate */
3960
} else {
3961
#if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3962
RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") is proxied by self\n"
3963
, FUNC_ADPT_ARG(adapter), MAC_ARG(da));
3964
#endif
3965
}
3966
}
3967
rtw_rcu_read_unlock();
3968
3969
if (!mppath) {
3970
#if DBG_RTW_MESH_FORWARD_MDA_SELF_COND
3971
RTW_INFO(FUNC_ADPT_FMT" DA("MAC_FMT") unknown\n"
3972
, FUNC_ADPT_ARG(adapter), MAC_ARG(da));
3973
#endif
3974
/* DA is unknown */
3975
#if 0 /* TODO: flags with AE bit */
3976
rtw_mesh_path_error_tx(adapter
3977
, adapter->mesh_cfg.element_ttl
3978
, mda, adapter->mesh_info.last_sn_update
3979
, WLAN_REASON_MESH_PATH_NOPROXY
3980
, msa
3981
);
3982
#endif
3983
}
3984
3985
/*
3986
* indicate to DS for both cases:
3987
* 1.) DA is proxied by self
3988
* 2.) DA is unknown
3989
*/
3990
#endif /* RTW_MESH_FORWARD_MDA_SELF_COND */
3991
act |= RTW_RX_MSDU_ACT_INDICATE;
3992
goto exit;
3993
}
3994
3995
fwd_chk:
3996
3997
if (adapter->stapriv.asoc_list_cnt <= 1)
3998
goto exit;
3999
4000
if (mctrl->ttl == 1) {
4001
minfo->mshstats.dropped_frames_ttl++;
4002
if (!act) {
4003
#ifdef DBG_RX_DROP_FRAME
4004
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" ttl reaches 0, not forwarding\n"
4005
, FUNC_ADPT_ARG(adapter));
4006
#endif
4007
}
4008
goto exit;
4009
}
4010
4011
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
4012
_rtw_init_listhead(b2u_list);
4013
#endif
4014
4015
ae_need = _rtw_memcmp(da , mda, ETH_ALEN) == _FALSE
4016
|| _rtw_memcmp(sa , msa, ETH_ALEN) == _FALSE;
4017
4018
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
4019
if (is_mda_bmc
4020
&& rtw_mfwd_b2u_policy_chk(mcfg->b2u_flags_mfwd, mda, rattrib->to_fr_ds == 3)
4021
) {
4022
bmc_need = rtw_mesh_data_bmc_to_uc(adapter
4023
, da, sa, mda, msa, ae_need, rframe->u.hdr.psta->cmn.mac_addr, mctrl->ttl - 1
4024
, b2u_list, &b2u_num, &fwd_mseq);
4025
}
4026
4027
if (bmc_need == _TRUE)
4028
#endif
4029
{
4030
xframe = rtw_alloc_xmitframe(&adapter->xmitpriv);
4031
if (!xframe) {
4032
#ifdef DBG_TX_DROP_FRAME
4033
RTW_INFO("DBG_TX_DROP_FRAME "FUNC_ADPT_FMT" rtw_alloc_xmitframe fail\n"
4034
, FUNC_ADPT_ARG(adapter));
4035
#endif
4036
goto exit;
4037
}
4038
4039
xattrib = &xframe->attrib;
4040
4041
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
4042
if (b2u_num)
4043
xattrib->mb2u = 1;
4044
else
4045
xattrib->mb2u = 0;
4046
#endif
4047
xattrib->mfwd_ttl = mctrl->ttl - 1;
4048
xattrib->mseq = fwd_mseq;
4049
_rtw_memcpy(xattrib->dst, da, ETH_ALEN);
4050
_rtw_memcpy(xattrib->src, sa, ETH_ALEN);
4051
_rtw_memcpy(xattrib->mda, mda, ETH_ALEN);
4052
_rtw_memcpy(xattrib->msa, msa, ETH_ALEN);
4053
_rtw_memcpy(xattrib->ta, adapter_mac_addr(adapter), ETH_ALEN);
4054
4055
if (is_mda_bmc) {
4056
xattrib->mesh_frame_mode = ae_need ? MESH_BMCAST_PX_DATA : MESH_BMCAST_DATA;
4057
_rtw_memcpy(xattrib->ra, mda, ETH_ALEN);
4058
} else {
4059
xattrib->mesh_frame_mode = ae_need ? MESH_UCAST_PX_DATA : MESH_UCAST_DATA;
4060
_rtw_memcpy(xattrib->ra, fwd_ra, ETH_ALEN);
4061
}
4062
4063
*fwd_frame = xframe;
4064
}
4065
4066
act |= RTW_RX_MSDU_ACT_FORWARD;
4067
if (is_mda_bmc)
4068
minfo->mshstats.fwded_mcast++;
4069
else
4070
minfo->mshstats.fwded_unicast++;
4071
minfo->mshstats.fwded_frames++;
4072
4073
exit:
4074
return act;
4075
}
4076
4077
void dump_mesh_stats(void *sel, _adapter *adapter)
4078
{
4079
struct rtw_mesh_info *minfo = &adapter->mesh_info;
4080
struct rtw_mesh_stats *stats = &minfo->mshstats;
4081
4082
RTW_PRINT_SEL(sel, "fwd_bmc:%u\n", stats->fwded_mcast);
4083
RTW_PRINT_SEL(sel, "fwd_uc:%u\n", stats->fwded_unicast);
4084
4085
RTW_PRINT_SEL(sel, "drop_ttl:%u\n", stats->dropped_frames_ttl);
4086
RTW_PRINT_SEL(sel, "drop_no_route:%u\n", stats->dropped_frames_no_route);
4087
RTW_PRINT_SEL(sel, "drop_congestion:%u\n", stats->dropped_frames_congestion);
4088
RTW_PRINT_SEL(sel, "drop_dup:%u\n", stats->dropped_frames_duplicate);
4089
4090
RTW_PRINT_SEL(sel, "mrc_del_qlen:%u\n", stats->mrc_del_qlen);
4091
}
4092
#endif /* CONFIG_RTW_MESH */
4093
4094
4095