Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
nu11secur1ty
GitHub Repository: nu11secur1ty/Kali-Linux
Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_recv.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_RECV_C_
16
17
#include <drv_types.h>
18
#include <hal_data.h>
19
20
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
21
static void rtw_signal_stat_timer_hdl(void *ctx);
22
23
enum {
24
SIGNAL_STAT_CALC_PROFILE_0 = 0,
25
SIGNAL_STAT_CALC_PROFILE_1,
26
SIGNAL_STAT_CALC_PROFILE_MAX
27
};
28
29
u8 signal_stat_calc_profile[SIGNAL_STAT_CALC_PROFILE_MAX][2] = {
30
{4, 1}, /* Profile 0 => pre_stat : curr_stat = 4 : 1 */
31
{3, 7} /* Profile 1 => pre_stat : curr_stat = 3 : 7 */
32
};
33
34
#ifndef RTW_SIGNAL_STATE_CALC_PROFILE
35
#define RTW_SIGNAL_STATE_CALC_PROFILE SIGNAL_STAT_CALC_PROFILE_1
36
#endif
37
38
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
39
40
u8 rtw_bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
41
u8 rtw_rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
42
static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
43
static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
44
#ifdef CONFIG_TDLS
45
static u8 SNAP_ETH_TYPE_TDLS[2] = {0x89, 0x0d};
46
#endif
47
48
#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
49
int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe);
50
#endif
51
void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
52
{
53
54
55
56
_rtw_memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
57
58
_rtw_spinlock_init(&psta_recvpriv->lock);
59
60
/* for(i=0; i<MAX_RX_NUMBLKS; i++) */
61
/* _rtw_init_queue(&psta_recvpriv->blk_strms[i]); */
62
63
_rtw_init_queue(&psta_recvpriv->defrag_q);
64
65
66
}
67
68
sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter)
69
{
70
sint i;
71
72
union recv_frame *precvframe;
73
sint res = _SUCCESS;
74
75
76
/* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
77
/* _rtw_memset((unsigned char *)precvpriv, 0, sizeof (struct recv_priv)); */
78
79
_rtw_spinlock_init(&precvpriv->lock);
80
81
#ifdef CONFIG_RECV_THREAD_MODE
82
_rtw_init_sema(&precvpriv->recv_sema, 0);
83
84
#endif
85
86
_rtw_init_queue(&precvpriv->free_recv_queue);
87
_rtw_init_queue(&precvpriv->recv_pending_queue);
88
_rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
89
90
precvpriv->adapter = padapter;
91
92
precvpriv->free_recvframe_cnt = NR_RECVFRAME;
93
94
precvpriv->sink_udpport = 0;
95
precvpriv->pre_rtp_rxseq = 0;
96
precvpriv->cur_rtp_rxseq = 0;
97
98
#ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
99
precvpriv->store_law_data_flag = 1;
100
#else
101
precvpriv->store_law_data_flag = 0;
102
#endif
103
104
rtw_os_recv_resource_init(precvpriv, padapter);
105
106
precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
107
108
if (precvpriv->pallocated_frame_buf == NULL) {
109
res = _FAIL;
110
goto exit;
111
}
112
/* _rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); */
113
114
precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
115
/* precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - */
116
/* ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); */
117
118
precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
119
120
121
for (i = 0; i < NR_RECVFRAME ; i++) {
122
_rtw_init_listhead(&(precvframe->u.list));
123
124
rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
125
126
rtw_os_recv_resource_alloc(padapter, precvframe);
127
128
precvframe->u.hdr.len = 0;
129
130
precvframe->u.hdr.adapter = padapter;
131
precvframe++;
132
133
}
134
135
#ifdef CONFIG_USB_HCI
136
137
ATOMIC_SET(&(precvpriv->rx_pending_cnt), 1);
138
139
_rtw_init_sema(&precvpriv->allrxreturnevt, 0);
140
141
#endif
142
143
res = rtw_hal_init_recv_priv(padapter);
144
145
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
146
rtw_init_timer(&precvpriv->signal_stat_timer, padapter, rtw_signal_stat_timer_hdl, padapter);
147
148
precvpriv->signal_stat_sampling_interval = 2000; /* ms */
149
/* precvpriv->signal_stat_converging_constant = 5000; */ /* ms */
150
151
rtw_set_signal_stat_timer(precvpriv);
152
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
153
154
exit:
155
156
157
return res;
158
159
}
160
161
void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv);
162
void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv)
163
{
164
_rtw_spinlock_free(&precvpriv->lock);
165
#ifdef CONFIG_RECV_THREAD_MODE
166
_rtw_free_sema(&precvpriv->recv_sema);
167
#endif
168
169
_rtw_spinlock_free(&precvpriv->free_recv_queue.lock);
170
_rtw_spinlock_free(&precvpriv->recv_pending_queue.lock);
171
172
_rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock);
173
174
#ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
175
_rtw_spinlock_free(&precvpriv->recv_buf_pending_queue.lock);
176
#endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
177
}
178
179
void _rtw_free_recv_priv(struct recv_priv *precvpriv)
180
{
181
_adapter *padapter = precvpriv->adapter;
182
183
184
rtw_free_uc_swdec_pending_queue(padapter);
185
186
rtw_mfree_recv_priv_lock(precvpriv);
187
188
rtw_os_recv_resource_free(precvpriv);
189
190
if (precvpriv->pallocated_frame_buf)
191
rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
192
193
rtw_hal_free_recv_priv(padapter);
194
195
196
}
197
198
bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset)
199
{
200
#define DBG_RFRAME_DEL_WFD_IE 0
201
u8 *ies = rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + ies_offset;
202
uint ies_len_ori = rframe->u.hdr.len - (ies - rframe->u.hdr.rx_data);
203
uint ies_len;
204
205
ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_RFRAME_DEL_WFD_IE ? __func__ : NULL);
206
rframe->u.hdr.len -= ies_len_ori - ies_len;
207
208
return ies_len_ori != ies_len;
209
}
210
211
union recv_frame *_rtw_alloc_recvframe(_queue *pfree_recv_queue)
212
{
213
214
union recv_frame *precvframe;
215
_list *plist, *phead;
216
_adapter *padapter;
217
struct recv_priv *precvpriv;
218
219
if (_rtw_queue_empty(pfree_recv_queue) == _TRUE)
220
precvframe = NULL;
221
else {
222
phead = get_list_head(pfree_recv_queue);
223
224
plist = get_next(phead);
225
226
precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
227
228
rtw_list_delete(&precvframe->u.hdr.list);
229
padapter = precvframe->u.hdr.adapter;
230
if (padapter != NULL) {
231
precvpriv = &padapter->recvpriv;
232
if (pfree_recv_queue == &precvpriv->free_recv_queue)
233
precvpriv->free_recvframe_cnt--;
234
}
235
}
236
237
238
return precvframe;
239
240
}
241
242
union recv_frame *rtw_alloc_recvframe(_queue *pfree_recv_queue)
243
{
244
_irqL irqL;
245
union recv_frame *precvframe;
246
247
_enter_critical_bh(&pfree_recv_queue->lock, &irqL);
248
249
precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
250
251
_exit_critical_bh(&pfree_recv_queue->lock, &irqL);
252
253
return precvframe;
254
}
255
256
void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv)
257
{
258
/* Perry: This can be removed */
259
_rtw_init_listhead(&precvframe->u.hdr.list);
260
261
precvframe->u.hdr.len = 0;
262
}
263
264
int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue)
265
{
266
_irqL irqL;
267
_adapter *padapter = precvframe->u.hdr.adapter;
268
struct recv_priv *precvpriv = &padapter->recvpriv;
269
270
271
#ifdef CONFIG_CONCURRENT_MODE
272
padapter = GET_PRIMARY_ADAPTER(padapter);
273
precvpriv = &padapter->recvpriv;
274
pfree_recv_queue = &precvpriv->free_recv_queue;
275
precvframe->u.hdr.adapter = padapter;
276
#endif
277
278
279
rtw_os_free_recvframe(precvframe);
280
281
282
_enter_critical_bh(&pfree_recv_queue->lock, &irqL);
283
284
rtw_list_delete(&(precvframe->u.hdr.list));
285
286
precvframe->u.hdr.len = 0;
287
288
rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
289
290
if (padapter != NULL) {
291
if (pfree_recv_queue == &precvpriv->free_recv_queue)
292
precvpriv->free_recvframe_cnt++;
293
}
294
295
_exit_critical_bh(&pfree_recv_queue->lock, &irqL);
296
297
298
return _SUCCESS;
299
300
}
301
302
303
304
305
sint _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
306
{
307
308
_adapter *padapter = precvframe->u.hdr.adapter;
309
struct recv_priv *precvpriv = &padapter->recvpriv;
310
311
312
/* _rtw_init_listhead(&(precvframe->u.hdr.list)); */
313
rtw_list_delete(&(precvframe->u.hdr.list));
314
315
316
rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue));
317
318
if (padapter != NULL) {
319
if (queue == &precvpriv->free_recv_queue)
320
precvpriv->free_recvframe_cnt++;
321
}
322
323
324
return _SUCCESS;
325
}
326
327
sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
328
{
329
sint ret;
330
_irqL irqL;
331
332
/* _spinlock(&pfree_recv_queue->lock); */
333
_enter_critical_bh(&queue->lock, &irqL);
334
ret = _rtw_enqueue_recvframe(precvframe, queue);
335
/* _rtw_spinunlock(&pfree_recv_queue->lock); */
336
_exit_critical_bh(&queue->lock, &irqL);
337
338
return ret;
339
}
340
341
/*
342
sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
343
{
344
return rtw_free_recvframe(precvframe, queue);
345
}
346
*/
347
348
349
350
351
/*
352
caller : defrag ; recvframe_chk_defrag in recv_thread (passive)
353
pframequeue: defrag_queue : will be accessed in recv_thread (passive)
354
355
using spinlock to protect
356
357
*/
358
359
void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue)
360
{
361
union recv_frame *precvframe;
362
_list *plist, *phead;
363
364
_rtw_spinlock(&pframequeue->lock);
365
366
phead = get_list_head(pframequeue);
367
plist = get_next(phead);
368
369
while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
370
precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
371
372
plist = get_next(plist);
373
374
/* rtw_list_delete(&precvframe->u.hdr.list); */ /* will do this in rtw_free_recvframe() */
375
376
rtw_free_recvframe(precvframe, pfree_recv_queue);
377
}
378
379
_rtw_spinunlock(&pframequeue->lock);
380
381
382
}
383
384
u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter)
385
{
386
u32 cnt = 0;
387
union recv_frame *pending_frame;
388
while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
389
rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
390
cnt++;
391
}
392
393
if (cnt)
394
RTW_INFO(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt);
395
396
return cnt;
397
}
398
399
400
sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue)
401
{
402
_irqL irqL;
403
404
_enter_critical_bh(&queue->lock, &irqL);
405
406
rtw_list_delete(&precvbuf->list);
407
rtw_list_insert_head(&precvbuf->list, get_list_head(queue));
408
409
_exit_critical_bh(&queue->lock, &irqL);
410
411
return _SUCCESS;
412
}
413
414
sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue)
415
{
416
_irqL irqL;
417
#ifdef CONFIG_SDIO_HCI
418
_enter_critical_bh(&queue->lock, &irqL);
419
#else
420
_enter_critical_ex(&queue->lock, &irqL);
421
#endif/*#ifdef CONFIG_SDIO_HCI*/
422
423
rtw_list_delete(&precvbuf->list);
424
425
rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
426
#ifdef CONFIG_SDIO_HCI
427
_exit_critical_bh(&queue->lock, &irqL);
428
#else
429
_exit_critical_ex(&queue->lock, &irqL);
430
#endif/*#ifdef CONFIG_SDIO_HCI*/
431
return _SUCCESS;
432
433
}
434
435
struct recv_buf *rtw_dequeue_recvbuf(_queue *queue)
436
{
437
_irqL irqL;
438
struct recv_buf *precvbuf;
439
_list *plist, *phead;
440
441
#ifdef CONFIG_SDIO_HCI
442
_enter_critical_bh(&queue->lock, &irqL);
443
#else
444
_enter_critical_ex(&queue->lock, &irqL);
445
#endif/*#ifdef CONFIG_SDIO_HCI*/
446
447
if (_rtw_queue_empty(queue) == _TRUE)
448
precvbuf = NULL;
449
else {
450
phead = get_list_head(queue);
451
452
plist = get_next(phead);
453
454
precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
455
456
rtw_list_delete(&precvbuf->list);
457
458
}
459
460
#ifdef CONFIG_SDIO_HCI
461
_exit_critical_bh(&queue->lock, &irqL);
462
#else
463
_exit_critical_ex(&queue->lock, &irqL);
464
#endif/*#ifdef CONFIG_SDIO_HCI*/
465
466
return precvbuf;
467
468
}
469
470
sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe);
471
sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe)
472
{
473
474
sint i, res = _SUCCESS;
475
u32 datalen;
476
u8 miccode[8];
477
u8 bmic_err = _FALSE, brpt_micerror = _TRUE;
478
u8 *pframe, *payload, *pframemic;
479
u8 *mickey;
480
/* u8 *iv,rxdata_key_idx=0; */
481
struct sta_info *stainfo;
482
struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib;
483
struct security_priv *psecuritypriv = &adapter->securitypriv;
484
485
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
486
struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
487
488
stainfo = rtw_get_stainfo(&adapter->stapriv , &prxattrib->ta[0]);
489
490
if (prxattrib->encrypt == _TKIP_) {
491
492
/* calculate mic code */
493
if (stainfo != NULL) {
494
if (IS_MCAST(prxattrib->ra)) {
495
/* mickey=&psecuritypriv->dot118021XGrprxmickey.skey[0]; */
496
/* iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; */
497
/* rxdata_key_idx =( ((iv[3])>>6)&0x3) ; */
498
mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
499
500
/* RTW_INFO("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d),pmlmeinfo->key_index(%d) ,recv key_id(%d)\n", */
501
/* psecuritypriv->dot118021XGrpKeyid,pmlmeinfo->key_index,rxdata_key_idx); */
502
503
if (psecuritypriv->binstallGrpkey == _FALSE) {
504
res = _FAIL;
505
RTW_INFO("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
506
goto exit;
507
}
508
} else {
509
mickey = &stainfo->dot11tkiprxmickey.skey[0];
510
}
511
512
datalen = precvframe->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8; /* icv_len included the mic code */
513
pframe = precvframe->u.hdr.rx_data;
514
payload = pframe + prxattrib->hdrlen + prxattrib->iv_len;
515
516
517
/* rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); */ /* care the length of the data */
518
519
rtw_seccalctkipmic(mickey, pframe, payload, datalen , &miccode[0], (unsigned char)prxattrib->priority); /* care the length of the data */
520
521
pframemic = payload + datalen;
522
523
bmic_err = _FALSE;
524
525
for (i = 0; i < 8; i++) {
526
if (miccode[i] != *(pframemic + i)) {
527
bmic_err = _TRUE;
528
}
529
}
530
531
532
if (bmic_err == _TRUE) {
533
534
535
536
/* double check key_index for some timing issue , */
537
/* cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
538
if ((IS_MCAST(prxattrib->ra) == _TRUE) && (prxattrib->key_index != pmlmeinfo->key_index))
539
brpt_micerror = _FALSE;
540
541
if ((prxattrib->bdecrypted == _TRUE) && (brpt_micerror == _TRUE)) {
542
rtw_handle_tkip_mic_err(adapter, stainfo, (u8)IS_MCAST(prxattrib->ra));
543
RTW_INFO(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
544
} else {
545
RTW_INFO(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
546
}
547
548
res = _FAIL;
549
550
} else {
551
/* mic checked ok */
552
if ((psecuritypriv->bcheck_grpkey == _FALSE) && (IS_MCAST(prxattrib->ra) == _TRUE)) {
553
psecuritypriv->bcheck_grpkey = _TRUE;
554
}
555
}
556
557
}
558
559
recvframe_pull_tail(precvframe, 8);
560
561
}
562
563
exit:
564
565
566
return res;
567
568
}
569
570
/*#define DBG_RX_SW_DECRYPTOR*/
571
572
/* decrypt and set the ivlen,icvlen of the recv_frame */
573
union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame);
574
union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame)
575
{
576
577
struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
578
struct security_priv *psecuritypriv = &padapter->securitypriv;
579
union recv_frame *return_packet = precv_frame;
580
u32 res = _SUCCESS;
581
582
583
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt);
584
585
586
if (prxattrib->encrypt > 0) {
587
u8 *iv = precv_frame->u.hdr.rx_data + prxattrib->hdrlen;
588
prxattrib->key_index = (((iv[3]) >> 6) & 0x3) ;
589
590
if (prxattrib->key_index > WEP_KEYS) {
591
RTW_INFO("prxattrib->key_index(%d) > WEP_KEYS\n", prxattrib->key_index);
592
593
switch (prxattrib->encrypt) {
594
case _WEP40_:
595
case _WEP104_:
596
prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
597
break;
598
case _TKIP_:
599
case _AES_:
600
default:
601
prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
602
break;
603
}
604
}
605
}
606
607
if (prxattrib->encrypt && !prxattrib->bdecrypted) {
608
if (GetFrameType(get_recvframe_data(precv_frame)) == WIFI_DATA
609
#ifdef CONFIG_CONCURRENT_MODE
610
&& !IS_MCAST(prxattrib->ra) /* bc/mc packets may use sw decryption for concurrent mode */
611
#endif
612
)
613
psecuritypriv->hw_decrypted = _FALSE;
614
615
#ifdef DBG_RX_SW_DECRYPTOR
616
RTW_INFO(ADPT_FMT" - sec_type:%s DO SW decryption\n",
617
ADPT_ARG(padapter), security_type_str(prxattrib->encrypt));
618
#endif
619
620
#ifdef DBG_RX_DECRYPTOR
621
RTW_INFO("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
622
__FUNCTION__,
623
__LINE__,
624
prxattrib->bdecrypted,
625
prxattrib->encrypt,
626
psecuritypriv->hw_decrypted);
627
#endif
628
629
switch (prxattrib->encrypt) {
630
case _WEP40_:
631
case _WEP104_:
632
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep);
633
rtw_wep_decrypt(padapter, (u8 *)precv_frame);
634
break;
635
case _TKIP_:
636
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip);
637
res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
638
break;
639
case _AES_:
640
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes);
641
res = rtw_aes_decrypt(padapter, (u8 *)precv_frame);
642
break;
643
#ifdef CONFIG_WAPI_SUPPORT
644
case _SMS4_:
645
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wapi);
646
rtw_sms4_decrypt(padapter, (u8 *)precv_frame);
647
break;
648
#endif
649
default:
650
break;
651
}
652
} else if (prxattrib->bdecrypted == 1
653
&& prxattrib->encrypt > 0
654
&& (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)
655
) {
656
#if 0
657
if ((prxstat->icv == 1) && (prxattrib->encrypt != _AES_)) {
658
psecuritypriv->hw_decrypted = _FALSE;
659
660
661
rtw_free_recvframe(precv_frame, &padapter->recvpriv.free_recv_queue);
662
663
return_packet = NULL;
664
665
} else
666
#endif
667
{
668
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw);
669
670
psecuritypriv->hw_decrypted = _TRUE;
671
#ifdef DBG_RX_DECRYPTOR
672
RTW_INFO("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
673
__FUNCTION__,
674
__LINE__,
675
prxattrib->bdecrypted,
676
prxattrib->encrypt,
677
psecuritypriv->hw_decrypted);
678
679
#endif
680
}
681
} else {
682
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown);
683
#ifdef DBG_RX_DECRYPTOR
684
RTW_INFO("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
685
__FUNCTION__,
686
__LINE__,
687
prxattrib->bdecrypted,
688
prxattrib->encrypt,
689
psecuritypriv->hw_decrypted);
690
#endif
691
}
692
693
#ifdef CONFIG_RTW_MESH
694
if (res != _FAIL
695
&& !prxattrib->amsdu
696
&& prxattrib->mesh_ctrl_present)
697
res = rtw_mesh_rx_validate_mctrl_non_amsdu(padapter, precv_frame);
698
#endif
699
700
if (res == _FAIL) {
701
rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
702
return_packet = NULL;
703
} else
704
prxattrib->bdecrypted = _TRUE;
705
/* recvframe_chkmic(adapter, precv_frame); */ /* move to recvframme_defrag function */
706
707
708
return return_packet;
709
710
}
711
/* ###set the security information in the recv_frame */
712
union recv_frame *portctrl(_adapter *adapter, union recv_frame *precv_frame);
713
union recv_frame *portctrl(_adapter *adapter, union recv_frame *precv_frame)
714
{
715
u8 *psta_addr = NULL;
716
u8 *ptr;
717
uint auth_alg;
718
struct recv_frame_hdr *pfhdr;
719
struct sta_info *psta;
720
struct sta_priv *pstapriv ;
721
union recv_frame *prtnframe;
722
u16 ether_type = 0;
723
u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */
724
struct rx_pkt_attrib *pattrib;
725
726
727
pstapriv = &adapter->stapriv;
728
729
auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
730
731
ptr = get_recvframe_data(precv_frame);
732
pfhdr = &precv_frame->u.hdr;
733
pattrib = &pfhdr->attrib;
734
psta_addr = pattrib->ta;
735
736
prtnframe = NULL;
737
738
psta = rtw_get_stainfo(pstapriv, psta_addr);
739
740
741
if (auth_alg == dot11AuthAlgrthm_8021X) {
742
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
743
/* blocked */
744
/* only accept EAPOL frame */
745
746
prtnframe = precv_frame;
747
748
/* get ether_type */
749
ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
750
_rtw_memcpy(&ether_type, ptr, 2);
751
ether_type = ntohs((unsigned short)ether_type);
752
753
if (ether_type == eapol_type)
754
prtnframe = precv_frame;
755
else {
756
/* free this frame */
757
rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
758
prtnframe = NULL;
759
}
760
} else {
761
/* allowed */
762
/* check decryption status, and decrypt the frame if needed */
763
764
765
prtnframe = precv_frame;
766
/* check is the EAPOL frame or not (Rekey) */
767
/* if(ether_type == eapol_type){ */
768
/* check Rekey */
769
770
/* prtnframe=precv_frame; */
771
/* } */
772
}
773
} else
774
prtnframe = precv_frame;
775
776
777
return prtnframe;
778
779
}
780
781
/* VALID_PN_CHK
782
* Return true when PN is legal, otherwise false.
783
* Legal PN:
784
* 1. If old PN is 0, any PN is legal
785
* 2. PN > old PN
786
*/
787
#define PN_LESS_CHK(a, b) (((a-b) & 0x800000000000) != 0)
788
#define VALID_PN_CHK(new, old) (((old) == 0) || PN_LESS_CHK(old, new))
789
#define CCMPH_2_KEYID(ch) (((ch) & 0x00000000c0000000) >> 30)
790
sint recv_ucast_pn_decache(union recv_frame *precv_frame);
791
sint recv_ucast_pn_decache(union recv_frame *precv_frame)
792
{
793
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
794
struct sta_info *sta = precv_frame->u.hdr.psta;
795
struct stainfo_rxcache *prxcache = &sta->sta_recvpriv.rxcache;
796
u8 *pdata = precv_frame->u.hdr.rx_data;
797
sint tid = precv_frame->u.hdr.attrib.priority;
798
u64 tmp_iv_hdr = 0;
799
u64 curr_pn = 0, pkt_pn = 0;
800
801
if (tid > 15)
802
return _FAIL;
803
804
if (pattrib->encrypt == _AES_) {
805
tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen));
806
pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
807
tmp_iv_hdr = le64_to_cpu(*(u64*)prxcache->iv[tid]);
808
curr_pn = CCMPH_2_PN(tmp_iv_hdr);
809
810
if (!VALID_PN_CHK(pkt_pn, curr_pn)) {
811
/* return _FAIL; */
812
} else {
813
prxcache->last_tid = tid;
814
_rtw_memcpy(prxcache->iv[tid],
815
(pdata + pattrib->hdrlen),
816
sizeof(prxcache->iv[tid]));
817
}
818
}
819
820
return _SUCCESS;
821
}
822
823
sint recv_bcast_pn_decache(union recv_frame *precv_frame);
824
sint recv_bcast_pn_decache(union recv_frame *precv_frame)
825
{
826
_adapter *padapter = precv_frame->u.hdr.adapter;
827
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
828
struct security_priv *psecuritypriv = &padapter->securitypriv;
829
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
830
u8 *pdata = precv_frame->u.hdr.rx_data;
831
u64 tmp_iv_hdr = 0;
832
u64 curr_pn = 0, pkt_pn = 0;
833
u8 key_id;
834
835
if ((pattrib->encrypt == _AES_) &&
836
(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
837
838
tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen));
839
key_id = CCMPH_2_KEYID(tmp_iv_hdr);
840
pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
841
842
curr_pn = le64_to_cpu(*(u64*)psecuritypriv->iv_seq[key_id]);
843
curr_pn &= 0x0000ffffffffffff;
844
845
if (!VALID_PN_CHK(pkt_pn, curr_pn))
846
return _FAIL;
847
848
*(u64*)psecuritypriv->iv_seq[key_id] = cpu_to_le64(pkt_pn);
849
}
850
851
return _SUCCESS;
852
}
853
854
sint recv_decache(union recv_frame *precv_frame)
855
{
856
struct sta_info *psta = precv_frame->u.hdr.psta;
857
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
858
_adapter *adapter = psta->padapter;
859
sint tid = pattrib->priority;
860
u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) |
861
(precv_frame->u.hdr.attrib.frag_num & 0xf);
862
u16 *prxseq;
863
864
if (tid > 15)
865
return _FAIL;
866
867
if (pattrib->qos) {
868
if (IS_MCAST(pattrib->ra))
869
prxseq = &psta->sta_recvpriv.bmc_tid_rxseq[tid];
870
else
871
prxseq = &psta->sta_recvpriv.rxcache.tid_rxseq[tid];
872
} else {
873
if (IS_MCAST(pattrib->ra)) {
874
prxseq = &psta->sta_recvpriv.nonqos_bmc_rxseq;
875
#ifdef DBG_RX_SEQ
876
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" nonqos bmc seq_num:%d\n"
877
, FUNC_ADPT_ARG(adapter), pattrib->seq_num);
878
#endif
879
880
} else {
881
prxseq = &psta->sta_recvpriv.nonqos_rxseq;
882
#ifdef DBG_RX_SEQ
883
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" nonqos seq_num:%d\n"
884
, FUNC_ADPT_ARG(adapter), pattrib->seq_num);
885
#endif
886
}
887
}
888
889
if (seq_ctrl == *prxseq) {
890
/* for non-AMPDU case */
891
psta->sta_stats.duplicate_cnt++;
892
893
if (psta->sta_stats.duplicate_cnt % 100 == 0)
894
RTW_INFO("%s: tid=%u seq=%d frag=%d\n", __func__
895
, tid, precv_frame->u.hdr.attrib.seq_num
896
, precv_frame->u.hdr.attrib.frag_num);
897
898
#ifdef DBG_RX_DROP_FRAME
899
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv_decache _FAIL for sta="MAC_FMT"\n"
900
, FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr));
901
#endif
902
return _FAIL;
903
}
904
*prxseq = seq_ctrl;
905
906
return _SUCCESS;
907
}
908
909
void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta)
910
{
911
#ifdef CONFIG_AP_MODE
912
unsigned char pwrbit;
913
u8 *ptr = precv_frame->u.hdr.rx_data;
914
915
pwrbit = GetPwrMgt(ptr);
916
917
if (pwrbit) {
918
if (!(psta->state & WIFI_SLEEP_STATE)) {
919
/* psta->state |= WIFI_SLEEP_STATE; */
920
/* rtw_tim_map_set(padapter, pstapriv->sta_dz_bitmap, BIT(psta->cmn.aid)); */
921
922
stop_sta_xmit(padapter, psta);
923
/* RTW_INFO_DUMP("to sleep, sta_dz_bitmap=", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len); */
924
}
925
} else {
926
if (psta->state & WIFI_SLEEP_STATE) {
927
/* psta->state ^= WIFI_SLEEP_STATE; */
928
/* rtw_tim_map_clear(padapter, pstapriv->sta_dz_bitmap, BIT(psta->cmn.aid)); */
929
930
wakeup_sta_to_xmit(padapter, psta);
931
/* RTW_INFO_DUMP("to wakeup, sta_dz_bitmap=", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len); */
932
}
933
}
934
#endif
935
}
936
937
void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta)
938
{
939
#ifdef CONFIG_AP_MODE
940
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
941
942
#ifdef CONFIG_TDLS
943
if (!(psta->tdls_sta_state & TDLS_LINKED_STATE)) {
944
#endif /* CONFIG_TDLS */
945
946
if (!psta->qos_option)
947
return;
948
949
if (!(psta->qos_info & 0xf))
950
return;
951
952
#ifdef CONFIG_TDLS
953
}
954
#endif /* CONFIG_TDLS */
955
956
if (psta->state & WIFI_SLEEP_STATE) {
957
u8 wmmps_ac = 0;
958
959
switch (pattrib->priority) {
960
case 1:
961
case 2:
962
wmmps_ac = psta->uapsd_bk & BIT(1);
963
break;
964
case 4:
965
case 5:
966
wmmps_ac = psta->uapsd_vi & BIT(1);
967
break;
968
case 6:
969
case 7:
970
wmmps_ac = psta->uapsd_vo & BIT(1);
971
break;
972
case 0:
973
case 3:
974
default:
975
wmmps_ac = psta->uapsd_be & BIT(1);
976
break;
977
}
978
979
if (wmmps_ac) {
980
if (psta->sleepq_ac_len > 0) {
981
/* process received triggered frame */
982
xmit_delivery_enabled_frames(padapter, psta);
983
} else {
984
/* issue one qos null frame with More data bit = 0 and the EOSP bit set (=1) */
985
issue_qos_nulldata(padapter, psta->cmn.mac_addr, (u16)pattrib->priority, 0, 0, 0);
986
}
987
}
988
989
}
990
991
992
#endif
993
994
}
995
996
#ifdef CONFIG_TDLS
997
sint OnTDLS(_adapter *adapter, union recv_frame *precv_frame)
998
{
999
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1000
sint ret = _SUCCESS;
1001
u8 *paction = get_recvframe_data(precv_frame);
1002
u8 category_field = 1;
1003
#ifdef CONFIG_WFD
1004
u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a };
1005
#endif /* CONFIG_WFD */
1006
struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
1007
u8 *ptr = precv_frame->u.hdr.rx_data;
1008
struct sta_priv *pstapriv = &(adapter->stapriv);
1009
struct sta_info *ptdls_sta = NULL;
1010
1011
/* point to action field */
1012
paction += pattrib->hdrlen
1013
+ pattrib->iv_len
1014
+ SNAP_SIZE
1015
+ ETH_TYPE_LEN
1016
+ PAYLOAD_TYPE_LEN
1017
+ category_field;
1018
1019
RTW_INFO("[TDLS] Recv %s from "MAC_FMT" with SeqNum = %d\n", rtw_tdls_action_txt(*paction), MAC_ARG(pattrib->src), GetSequence(get_recvframe_data(precv_frame)));
1020
1021
if (hal_chk_wl_func(adapter, WL_FUNC_TDLS) == _FALSE) {
1022
RTW_INFO("Ignore tdls frame since hal doesn't support tdls\n");
1023
ret = _FAIL;
1024
return ret;
1025
}
1026
1027
if (rtw_is_tdls_enabled(adapter) == _FALSE) {
1028
RTW_INFO("recv tdls frame, "
1029
"but tdls haven't enabled\n");
1030
ret = _FAIL;
1031
return ret;
1032
}
1033
1034
ptdls_sta = rtw_get_stainfo(pstapriv, get_sa(ptr));
1035
if (ptdls_sta == NULL) {
1036
switch (*paction) {
1037
case TDLS_SETUP_REQUEST:
1038
case TDLS_DISCOVERY_REQUEST:
1039
break;
1040
default:
1041
RTW_INFO("[TDLS] %s - Direct Link Peer = "MAC_FMT" not found for action = %d\n", __func__, MAC_ARG(get_sa(ptr)), *paction);
1042
ret = _FAIL;
1043
goto exit;
1044
}
1045
}
1046
1047
switch (*paction) {
1048
case TDLS_SETUP_REQUEST:
1049
ret = On_TDLS_Setup_Req(adapter, precv_frame, ptdls_sta);
1050
break;
1051
case TDLS_SETUP_RESPONSE:
1052
ret = On_TDLS_Setup_Rsp(adapter, precv_frame, ptdls_sta);
1053
break;
1054
case TDLS_SETUP_CONFIRM:
1055
ret = On_TDLS_Setup_Cfm(adapter, precv_frame, ptdls_sta);
1056
break;
1057
case TDLS_TEARDOWN:
1058
ret = On_TDLS_Teardown(adapter, precv_frame, ptdls_sta);
1059
break;
1060
case TDLS_DISCOVERY_REQUEST:
1061
ret = On_TDLS_Dis_Req(adapter, precv_frame);
1062
break;
1063
case TDLS_PEER_TRAFFIC_INDICATION:
1064
ret = On_TDLS_Peer_Traffic_Indication(adapter, precv_frame, ptdls_sta);
1065
break;
1066
case TDLS_PEER_TRAFFIC_RESPONSE:
1067
ret = On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame, ptdls_sta);
1068
break;
1069
#ifdef CONFIG_TDLS_CH_SW
1070
case TDLS_CHANNEL_SWITCH_REQUEST:
1071
ret = On_TDLS_Ch_Switch_Req(adapter, precv_frame, ptdls_sta);
1072
break;
1073
case TDLS_CHANNEL_SWITCH_RESPONSE:
1074
ret = On_TDLS_Ch_Switch_Rsp(adapter, precv_frame, ptdls_sta);
1075
break;
1076
#endif
1077
#ifdef CONFIG_WFD
1078
/* First byte of WFA OUI */
1079
case 0x50:
1080
if (_rtw_memcmp(WFA_OUI, paction, 3)) {
1081
/* Probe request frame */
1082
if (*(paction + 3) == 0x04) {
1083
/* WFDTDLS: for sigma test, do not setup direct link automatically */
1084
ptdlsinfo->dev_discovered = _TRUE;
1085
RTW_INFO("recv tunneled probe request frame\n");
1086
issue_tunneled_probe_rsp(adapter, precv_frame);
1087
}
1088
/* Probe response frame */
1089
if (*(paction + 3) == 0x05) {
1090
/* WFDTDLS: for sigma test, do not setup direct link automatically */
1091
ptdlsinfo->dev_discovered = _TRUE;
1092
RTW_INFO("recv tunneled probe response frame\n");
1093
}
1094
}
1095
break;
1096
#endif /* CONFIG_WFD */
1097
default:
1098
RTW_INFO("receive TDLS frame %d but not support\n", *paction);
1099
ret = _FAIL;
1100
break;
1101
}
1102
1103
exit:
1104
return ret;
1105
1106
}
1107
#endif /* CONFIG_TDLS */
1108
1109
void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta)
1110
{
1111
int sz;
1112
struct sta_info *psta = NULL;
1113
struct stainfo_stats *pstats = NULL;
1114
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
1115
struct recv_priv *precvpriv = &padapter->recvpriv;
1116
1117
sz = get_recvframe_len(prframe);
1118
precvpriv->rx_bytes += sz;
1119
1120
padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
1121
1122
if ((!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst)))
1123
padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
1124
1125
if (sta)
1126
psta = sta;
1127
else
1128
psta = prframe->u.hdr.psta;
1129
1130
if (psta) {
1131
u8 is_ra_bmc = IS_MCAST(pattrib->ra);
1132
1133
pstats = &psta->sta_stats;
1134
1135
pstats->last_rx_time = rtw_get_current_time();
1136
pstats->rx_data_pkts++;
1137
pstats->rx_bytes += sz;
1138
if (is_broadcast_mac_addr(pattrib->ra)) {
1139
pstats->rx_data_bc_pkts++;
1140
pstats->rx_bc_bytes += sz;
1141
} else if (is_ra_bmc) {
1142
pstats->rx_data_mc_pkts++;
1143
pstats->rx_mc_bytes += sz;
1144
}
1145
1146
if (!is_ra_bmc) {
1147
pstats->rxratecnt[pattrib->data_rate]++;
1148
/*record rx packets for every tid*/
1149
pstats->rx_data_qos_pkts[pattrib->priority]++;
1150
}
1151
#ifdef CONFIG_DYNAMIC_SOML
1152
rtw_dyn_soml_byte_update(padapter, pattrib->data_rate, sz);
1153
#endif
1154
#if defined(CONFIG_CHECK_LEAVE_LPS) && defined(CONFIG_LPS_CHK_BY_TP)
1155
if (adapter_to_pwrctl(padapter)->lps_chk_by_tp)
1156
traffic_check_for_leave_lps_by_tp(padapter, _FALSE, psta);
1157
#endif /* CONFIG_LPS */
1158
1159
}
1160
1161
#ifdef CONFIG_CHECK_LEAVE_LPS
1162
#ifdef CONFIG_LPS_CHK_BY_TP
1163
if (!adapter_to_pwrctl(padapter)->lps_chk_by_tp)
1164
#endif
1165
traffic_check_for_leave_lps(padapter, _FALSE, 0);
1166
#endif /* CONFIG_CHECK_LEAVE_LPS */
1167
1168
}
1169
1170
sint sta2sta_data_frame(
1171
_adapter *adapter,
1172
union recv_frame *precv_frame,
1173
struct sta_info **psta
1174
)
1175
{
1176
u8 *ptr = precv_frame->u.hdr.rx_data;
1177
sint ret = _SUCCESS;
1178
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1179
struct sta_priv *pstapriv = &adapter->stapriv;
1180
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1181
u8 *mybssid = get_bssid(pmlmepriv);
1182
u8 *myhwaddr = adapter_mac_addr(adapter);
1183
u8 *sta_addr = pattrib->ta;
1184
sint bmcast = IS_MCAST(pattrib->dst);
1185
1186
#ifdef CONFIG_TDLS
1187
struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1188
#ifdef CONFIG_TDLS_CH_SW
1189
struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
1190
#endif
1191
struct sta_info *ptdls_sta = NULL;
1192
u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
1193
/* frame body located after [+2]: ether-type, [+1]: payload type */
1194
u8 *pframe_body = psnap_type + 2 + 1;
1195
#endif
1196
1197
1198
/* RTW_INFO("[%s] %d, seqnum:%d\n", __FUNCTION__, __LINE__, pattrib->seq_num); */
1199
1200
if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1201
(check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1202
1203
/* filter packets that SA is myself or multicast or broadcast */
1204
if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1205
ret = _FAIL;
1206
goto exit;
1207
}
1208
1209
if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1210
ret = _FAIL;
1211
goto exit;
1212
}
1213
1214
if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1215
_rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1216
(!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1217
ret = _FAIL;
1218
goto exit;
1219
}
1220
1221
} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
1222
#ifdef CONFIG_TDLS
1223
1224
/* direct link data transfer */
1225
if (ptdlsinfo->link_established == _TRUE) {
1226
*psta = ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->ta);
1227
if (ptdls_sta == NULL) {
1228
ret = _FAIL;
1229
goto exit;
1230
} else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1231
/* filter packets that SA is myself or multicast or broadcast */
1232
if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1233
ret = _FAIL;
1234
goto exit;
1235
}
1236
/* da should be for me */
1237
if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1238
ret = _FAIL;
1239
goto exit;
1240
}
1241
/* check BSSID */
1242
if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1243
_rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1244
(!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1245
ret = _FAIL;
1246
goto exit;
1247
}
1248
1249
#ifdef CONFIG_TDLS_CH_SW
1250
if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) {
1251
if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) {
1252
pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE;
1253
if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
1254
_cancel_timer_ex(&ptdls_sta->ch_sw_timer);
1255
/* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */
1256
}
1257
}
1258
#endif
1259
1260
/* process UAPSD tdls sta */
1261
process_pwrbit_data(adapter, precv_frame, ptdls_sta);
1262
1263
/* if NULL-frame, check pwrbit */
1264
if ((get_frame_sub_type(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) {
1265
/* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */
1266
if (GetPwrMgt(ptr)) {
1267
/* it would be triggered when we are off channel and receiving NULL DATA */
1268
/* we can confirm that peer STA is at off channel */
1269
RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n");
1270
/* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */
1271
}
1272
1273
/* TODO: Updated BSSID's seq. */
1274
/* RTW_INFO("drop Null Data\n"); */
1275
ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
1276
ret = _FAIL;
1277
goto exit;
1278
}
1279
1280
/* receive some of all TDLS management frames, process it at ON_TDLS */
1281
if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) {
1282
ret = OnTDLS(adapter, precv_frame);
1283
goto exit;
1284
}
1285
1286
if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE)
1287
process_wmmps_data(adapter, precv_frame, ptdls_sta);
1288
1289
ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
1290
1291
}
1292
} else
1293
#endif /* CONFIG_TDLS */
1294
{
1295
/* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
1296
if (!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
1297
ret = _FAIL;
1298
goto exit;
1299
}
1300
}
1301
1302
} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1303
if (bmcast) {
1304
/* For AP mode, if DA == MCAST, then BSSID should be also MCAST */
1305
if (!IS_MCAST(pattrib->bssid)) {
1306
ret = _FAIL;
1307
goto exit;
1308
}
1309
} else { /* not mc-frame */
1310
/* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
1311
if (!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
1312
ret = _FAIL;
1313
goto exit;
1314
}
1315
}
1316
1317
} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) {
1318
_rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1319
_rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
1320
_rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1321
_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1322
_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1323
1324
sta_addr = mybssid;
1325
} else
1326
ret = _FAIL;
1327
1328
#ifdef CONFIG_TDLS
1329
if (ptdls_sta == NULL)
1330
#endif
1331
*psta = rtw_get_stainfo(pstapriv, sta_addr);
1332
1333
if (*psta == NULL) {
1334
#ifdef CONFIG_MP_INCLUDED
1335
if (adapter->registrypriv.mp_mode == 1) {
1336
if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1337
adapter->mppriv.rx_pktloss++;
1338
}
1339
#endif
1340
ret = _FAIL;
1341
goto exit;
1342
}
1343
1344
exit:
1345
return ret;
1346
1347
}
1348
1349
sint ap2sta_data_frame(
1350
_adapter *adapter,
1351
union recv_frame *precv_frame,
1352
struct sta_info **psta)
1353
{
1354
u8 *ptr = precv_frame->u.hdr.rx_data;
1355
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1356
sint ret = _SUCCESS;
1357
struct sta_priv *pstapriv = &adapter->stapriv;
1358
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1359
u8 *mybssid = get_bssid(pmlmepriv);
1360
u8 *myhwaddr = adapter_mac_addr(adapter);
1361
sint bmcast = IS_MCAST(pattrib->dst);
1362
1363
1364
if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1365
&& (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE
1366
|| check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
1367
) {
1368
1369
/* filter packets that SA is myself or multicast or broadcast */
1370
if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1371
#ifdef DBG_RX_DROP_FRAME
1372
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" SA="MAC_FMT", myhwaddr="MAC_FMT"\n"
1373
, FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->src), MAC_ARG(myhwaddr));
1374
#endif
1375
ret = _FAIL;
1376
goto exit;
1377
}
1378
1379
/* da should be for me */
1380
if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1381
#ifdef DBG_RX_DROP_FRAME
1382
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA="MAC_FMT"\n"
1383
, FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->dst));
1384
#endif
1385
ret = _FAIL;
1386
goto exit;
1387
}
1388
1389
1390
/* check BSSID */
1391
if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1392
_rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1393
(!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1394
#ifdef DBG_RX_DROP_FRAME
1395
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" BSSID="MAC_FMT", mybssid="MAC_FMT"\n"
1396
, FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
1397
#endif
1398
#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
1399
if (!bmcast
1400
&& !IS_RADAR_DETECTED(adapter_to_rfctl(adapter))
1401
) {
1402
RTW_INFO(ADPT_FMT" -issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", ADPT_ARG(adapter), MAC_ARG(pattrib->bssid));
1403
issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1404
}
1405
#endif
1406
ret = _FAIL;
1407
goto exit;
1408
}
1409
1410
*psta = rtw_get_stainfo(pstapriv, pattrib->ta);
1411
if (*psta == NULL) {
1412
#ifdef DBG_RX_DROP_FRAME
1413
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under STATION_MODE ; drop pkt\n"
1414
, FUNC_ADPT_ARG(adapter));
1415
#endif
1416
ret = _FAIL;
1417
goto exit;
1418
}
1419
1420
/*if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1421
}
1422
*/
1423
1424
if (get_frame_sub_type(ptr) & BIT(6)) {
1425
/* No data, will not indicate to upper layer, temporily count it here */
1426
count_rx_stats(adapter, precv_frame, *psta);
1427
ret = RTW_RX_HANDLED;
1428
goto exit;
1429
}
1430
1431
} else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1432
(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
1433
_rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1434
_rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
1435
_rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1436
_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1437
_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1438
1439
1440
*psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1441
if (*psta == NULL) {
1442
#ifdef DBG_RX_DROP_FRAME
1443
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under WIFI_MP_STATE ; drop pkt\n"
1444
, FUNC_ADPT_ARG(adapter));
1445
#endif
1446
ret = _FAIL;
1447
goto exit;
1448
}
1449
1450
1451
} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1452
/* Special case */
1453
ret = RTW_RX_HANDLED;
1454
goto exit;
1455
} else {
1456
if (_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
1457
*psta = rtw_get_stainfo(pstapriv, pattrib->ta);
1458
if (*psta == NULL) {
1459
1460
/* for AP multicast issue , modify by yiwei */
1461
static systime send_issue_deauth_time = 0;
1462
1463
/* RTW_INFO("After send deauth , %u ms has elapsed.\n", rtw_get_passing_time_ms(send_issue_deauth_time)); */
1464
1465
if (rtw_get_passing_time_ms(send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) {
1466
send_issue_deauth_time = rtw_get_current_time();
1467
1468
RTW_INFO("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1469
1470
issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1471
}
1472
}
1473
}
1474
1475
ret = _FAIL;
1476
#ifdef DBG_RX_DROP_FRAME
1477
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" fw_state:0x%x\n"
1478
, FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
1479
#endif
1480
}
1481
1482
exit:
1483
1484
1485
return ret;
1486
1487
}
1488
1489
sint sta2ap_data_frame(
1490
_adapter *adapter,
1491
union recv_frame *precv_frame,
1492
struct sta_info **psta)
1493
{
1494
u8 *ptr = precv_frame->u.hdr.rx_data;
1495
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1496
struct sta_priv *pstapriv = &adapter->stapriv;
1497
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1498
unsigned char *mybssid = get_bssid(pmlmepriv);
1499
sint ret = _SUCCESS;
1500
1501
1502
if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1503
/* For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
1504
if (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1505
ret = _FAIL;
1506
goto exit;
1507
}
1508
1509
*psta = rtw_get_stainfo(pstapriv, pattrib->ta);
1510
if (*psta == NULL) {
1511
if (!IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) {
1512
#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
1513
RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1514
issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1515
#endif
1516
}
1517
1518
ret = RTW_RX_HANDLED;
1519
goto exit;
1520
}
1521
1522
process_pwrbit_data(adapter, precv_frame, *psta);
1523
1524
if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE)
1525
process_wmmps_data(adapter, precv_frame, *psta);
1526
1527
if (get_frame_sub_type(ptr) & BIT(6)) {
1528
/* No data, will not indicate to upper layer, temporily count it here */
1529
count_rx_stats(adapter, precv_frame, *psta);
1530
ret = RTW_RX_HANDLED;
1531
goto exit;
1532
}
1533
} else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1534
(check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
1535
/* RTW_INFO("%s ,in WIFI_MP_STATE\n",__func__); */
1536
_rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1537
_rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
1538
_rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1539
_rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1540
_rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1541
1542
1543
*psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1544
if (*psta == NULL) {
1545
#ifdef DBG_RX_DROP_FRAME
1546
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under WIFI_MP_STATE ; drop pkt\n"
1547
, FUNC_ADPT_ARG(adapter));
1548
#endif
1549
ret = _FAIL;
1550
goto exit;
1551
}
1552
1553
} else {
1554
u8 *myhwaddr = adapter_mac_addr(adapter);
1555
if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1556
ret = RTW_RX_HANDLED;
1557
goto exit;
1558
}
1559
#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
1560
RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1561
issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1562
#endif
1563
ret = RTW_RX_HANDLED;
1564
goto exit;
1565
}
1566
1567
exit:
1568
1569
1570
return ret;
1571
1572
}
1573
1574
sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame);
1575
sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame)
1576
{
1577
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1578
struct sta_priv *pstapriv = &padapter->stapriv;
1579
u8 *pframe = precv_frame->u.hdr.rx_data;
1580
struct sta_info *psta = NULL;
1581
/* uint len = precv_frame->u.hdr.len; */
1582
1583
/* RTW_INFO("+validate_recv_ctrl_frame\n"); */
1584
1585
if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1586
return _FAIL;
1587
1588
/* receive the frames that ra(a1) is my address */
1589
if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN))
1590
return _FAIL;
1591
1592
psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
1593
if (psta == NULL)
1594
return _FAIL;
1595
1596
/* for rx pkt statistics */
1597
psta->sta_stats.last_rx_time = rtw_get_current_time();
1598
psta->sta_stats.rx_ctrl_pkts++;
1599
1600
/* only handle ps-poll */
1601
if (get_frame_sub_type(pframe) == WIFI_PSPOLL) {
1602
#ifdef CONFIG_AP_MODE
1603
u16 aid;
1604
u8 wmmps_ac = 0;
1605
1606
aid = GetAid(pframe);
1607
if (psta->cmn.aid != aid)
1608
return _FAIL;
1609
1610
switch (pattrib->priority) {
1611
case 1:
1612
case 2:
1613
wmmps_ac = psta->uapsd_bk & BIT(0);
1614
break;
1615
case 4:
1616
case 5:
1617
wmmps_ac = psta->uapsd_vi & BIT(0);
1618
break;
1619
case 6:
1620
case 7:
1621
wmmps_ac = psta->uapsd_vo & BIT(0);
1622
break;
1623
case 0:
1624
case 3:
1625
default:
1626
wmmps_ac = psta->uapsd_be & BIT(0);
1627
break;
1628
}
1629
1630
if (wmmps_ac)
1631
return _FAIL;
1632
1633
if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1634
RTW_INFO("%s alive check-rx ps-poll\n", __func__);
1635
psta->expire_to = pstapriv->expire_to;
1636
psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1637
}
1638
1639
if ((psta->state & WIFI_SLEEP_STATE) && (rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid))) {
1640
_irqL irqL;
1641
_list *xmitframe_plist, *xmitframe_phead;
1642
struct xmit_frame *pxmitframe = NULL;
1643
struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1644
1645
/* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
1646
_enter_critical_bh(&pxmitpriv->lock, &irqL);
1647
1648
xmitframe_phead = get_list_head(&psta->sleep_q);
1649
xmitframe_plist = get_next(xmitframe_phead);
1650
1651
if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
1652
pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1653
1654
xmitframe_plist = get_next(xmitframe_plist);
1655
1656
rtw_list_delete(&pxmitframe->list);
1657
1658
psta->sleepq_len--;
1659
1660
if (psta->sleepq_len > 0)
1661
pxmitframe->attrib.mdata = 1;
1662
else
1663
pxmitframe->attrib.mdata = 0;
1664
1665
pxmitframe->attrib.triggered = 1;
1666
1667
/* RTW_INFO("handling ps-poll, q_len=%d\n", psta->sleepq_len); */
1668
/* RTW_INFO_DUMP("handling, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
1669
1670
#if 0
1671
_exit_critical_bh(&psta->sleep_q.lock, &irqL);
1672
if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
1673
rtw_os_xmit_complete(padapter, pxmitframe);
1674
_enter_critical_bh(&psta->sleep_q.lock, &irqL);
1675
#endif
1676
rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1677
1678
if (psta->sleepq_len == 0) {
1679
rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
1680
1681
/* RTW_INFO("after handling ps-poll\n"); */
1682
/* RTW_INFO_DUMP("after handling, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
1683
1684
/* upate BCN for TIM IE */
1685
/* update_BCNTIM(padapter); */
1686
update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0);
1687
}
1688
1689
/* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
1690
_exit_critical_bh(&pxmitpriv->lock, &irqL);
1691
1692
} else {
1693
/* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
1694
_exit_critical_bh(&pxmitpriv->lock, &irqL);
1695
1696
/* RTW_INFO("no buffered packets to xmit\n"); */
1697
if (rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid)) {
1698
if (psta->sleepq_len == 0) {
1699
RTW_INFO("no buffered packets to xmit\n");
1700
1701
/* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1702
issue_nulldata(padapter, psta->cmn.mac_addr, 0, 0, 0);
1703
} else {
1704
RTW_INFO("error!psta->sleepq_len=%d\n", psta->sleepq_len);
1705
psta->sleepq_len = 0;
1706
}
1707
1708
rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
1709
1710
/* upate BCN for TIM IE */
1711
/* update_BCNTIM(padapter); */
1712
update_beacon(padapter, _TIM_IE_, NULL, _TRUE, 0);
1713
}
1714
}
1715
}
1716
#endif /* CONFIG_AP_MODE */
1717
} else if (get_frame_sub_type(pframe) == WIFI_NDPA) {
1718
#ifdef CONFIG_BEAMFORMING
1719
rtw_beamforming_get_ndpa_frame(padapter, precv_frame);
1720
#endif/*CONFIG_BEAMFORMING*/
1721
} else if (get_frame_sub_type(pframe) == WIFI_BAR) {
1722
rtw_process_bar_frame(padapter, precv_frame);
1723
}
1724
1725
return _FAIL;
1726
1727
}
1728
1729
#if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
1730
static sint validate_mgmt_protect(_adapter *adapter, union recv_frame *precv_frame)
1731
{
1732
#define DBG_VALIDATE_MGMT_PROTECT 0
1733
#define DBG_VALIDATE_MGMT_DEC 0
1734
1735
struct security_priv *sec = &adapter->securitypriv;
1736
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1737
struct sta_info *psta = precv_frame->u.hdr.psta;
1738
u8 *ptr;
1739
u8 type;
1740
u8 subtype;
1741
u8 is_bmc;
1742
u8 category = 0xFF;
1743
1744
#ifdef CONFIG_IEEE80211W
1745
const u8 *igtk;
1746
u16 igtk_id;
1747
u64* ipn;
1748
#endif
1749
1750
u8 *mgmt_DATA;
1751
u32 data_len = 0;
1752
1753
sint ret;
1754
1755
#ifdef CONFIG_RTW_MESH
1756
if (MLME_IS_MESH(adapter)) {
1757
if (!adapter->mesh_info.mesh_auth_id)
1758
return pattrib->privacy ? _FAIL : _SUCCESS;
1759
} else
1760
#endif
1761
if (SEC_IS_BIP_KEY_INSTALLED(sec) == _FALSE)
1762
return _SUCCESS;
1763
1764
ptr = precv_frame->u.hdr.rx_data;
1765
type = GetFrameType(ptr);
1766
subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
1767
is_bmc = IS_MCAST(GetAddr1Ptr(ptr));
1768
1769
#if DBG_VALIDATE_MGMT_PROTECT
1770
if (subtype == WIFI_DEAUTH) {
1771
RTW_INFO(FUNC_ADPT_FMT" bmc:%u, deauth, privacy:%u, encrypt:%u, bdecrypted:%u\n"
1772
, FUNC_ADPT_ARG(adapter)
1773
, is_bmc, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1774
} else if (subtype == WIFI_DISASSOC) {
1775
RTW_INFO(FUNC_ADPT_FMT" bmc:%u, disassoc, privacy:%u, encrypt:%u, bdecrypted:%u\n"
1776
, FUNC_ADPT_ARG(adapter)
1777
, is_bmc, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1778
} if (subtype == WIFI_ACTION) {
1779
if (pattrib->privacy) {
1780
RTW_INFO(FUNC_ADPT_FMT" bmc:%u, action(?), privacy:%u, encrypt:%u, bdecrypted:%u\n"
1781
, FUNC_ADPT_ARG(adapter)
1782
, is_bmc, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1783
} else {
1784
RTW_INFO(FUNC_ADPT_FMT" bmc:%u, action(%u), privacy:%u, encrypt:%u, bdecrypted:%u\n"
1785
, FUNC_ADPT_ARG(adapter), is_bmc
1786
, *(ptr + sizeof(struct rtw_ieee80211_hdr_3addr))
1787
, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1788
}
1789
}
1790
#endif
1791
1792
if (!pattrib->privacy) {
1793
if (!psta || !(psta->flags & WLAN_STA_MFP)) {
1794
/* peer is not MFP capable, no need to check */
1795
goto exit;
1796
}
1797
1798
if (subtype == WIFI_ACTION)
1799
category = *(ptr + sizeof(struct rtw_ieee80211_hdr_3addr));
1800
1801
if (is_bmc) {
1802
/* broadcast cases */
1803
if (subtype == WIFI_ACTION) {
1804
if (CATEGORY_IS_GROUP_PRIVACY(category)) {
1805
/* drop broadcast group privacy action frame without encryption */
1806
#if DBG_VALIDATE_MGMT_PROTECT
1807
RTW_INFO(FUNC_ADPT_FMT" broadcast gp action(%u) w/o encrypt\n"
1808
, FUNC_ADPT_ARG(adapter), category);
1809
#endif
1810
goto fail;
1811
}
1812
if (CATEGORY_IS_ROBUST(category)) {
1813
/* broadcast robust action frame need BIP check */
1814
goto bip_verify;
1815
}
1816
}
1817
if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
1818
/* broadcast deauth or disassoc frame need BIP check */
1819
goto bip_verify;
1820
}
1821
goto exit;
1822
1823
} else {
1824
/* unicast cases */
1825
#ifdef CONFIG_IEEE80211W
1826
if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
1827
if (!MLME_IS_MESH(adapter)) {
1828
unsigned short reason = le16_to_cpu(*(unsigned short *)(ptr + WLAN_HDR_A3_LEN));
1829
1830
#if DBG_VALIDATE_MGMT_PROTECT
1831
RTW_INFO(FUNC_ADPT_FMT" unicast %s, reason=%d w/o encrypt\n"
1832
, FUNC_ADPT_ARG(adapter), subtype == WIFI_DEAUTH ? "deauth" : "disassoc", reason);
1833
#endif
1834
if (reason == 6 || reason == 7) {
1835
/* issue sa query request */
1836
issue_action_SA_Query(adapter, psta->cmn.mac_addr, 0, 0, IEEE80211W_RIGHT_KEY);
1837
}
1838
}
1839
goto fail;
1840
}
1841
#endif
1842
1843
if (subtype == WIFI_ACTION && CATEGORY_IS_ROBUST(category)) {
1844
if (psta->bpairwise_key_installed == _TRUE) {
1845
#if DBG_VALIDATE_MGMT_PROTECT
1846
RTW_INFO(FUNC_ADPT_FMT" unicast robust action(%d) w/o encrypt\n"
1847
, FUNC_ADPT_ARG(adapter), category);
1848
#endif
1849
goto fail;
1850
}
1851
}
1852
goto exit;
1853
}
1854
1855
bip_verify:
1856
#ifdef CONFIG_IEEE80211W
1857
#ifdef CONFIG_RTW_MESH
1858
if (MLME_IS_MESH(adapter)) {
1859
if (psta->igtk_bmp) {
1860
igtk = psta->igtk.skey;
1861
igtk_id = psta->igtk_id;
1862
ipn = &psta->igtk_pn.val;
1863
} else {
1864
/* mesh MFP without IGTK */
1865
goto exit;
1866
}
1867
} else
1868
#endif
1869
{
1870
igtk = sec->dot11wBIPKey[sec->dot11wBIPKeyid].skey;
1871
igtk_id = sec->dot11wBIPKeyid;
1872
ipn = &sec->dot11wBIPrxpn.val;
1873
}
1874
1875
/* verify BIP MME IE */
1876
ret = rtw_BIP_verify(adapter
1877
, get_recvframe_data(precv_frame)
1878
, get_recvframe_len(precv_frame)
1879
, igtk, igtk_id, ipn);
1880
if (ret == _FAIL) {
1881
/* RTW_INFO("802.11w BIP verify fail\n"); */
1882
goto fail;
1883
1884
} else if (ret == RTW_RX_HANDLED) {
1885
#if DBG_VALIDATE_MGMT_PROTECT
1886
RTW_INFO(FUNC_ADPT_FMT" none protected packet\n", FUNC_ADPT_ARG(adapter));
1887
#endif
1888
goto fail;
1889
}
1890
#endif /* CONFIG_IEEE80211W */
1891
goto exit;
1892
}
1893
1894
/* cases to decrypt mgmt frame */
1895
pattrib->bdecrypted = 0;
1896
pattrib->encrypt = _AES_;
1897
pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
1898
1899
/* set iv and icv length */
1900
SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1901
_rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1902
_rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
1903
1904
/* actual management data frame body */
1905
data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
1906
mgmt_DATA = rtw_zmalloc(data_len);
1907
if (mgmt_DATA == NULL) {
1908
RTW_INFO(FUNC_ADPT_FMT" mgmt allocate fail !!!!!!!!!\n", FUNC_ADPT_ARG(adapter));
1909
goto fail;
1910
}
1911
1912
#if DBG_VALIDATE_MGMT_DEC
1913
/* dump the packet content before decrypt */
1914
{
1915
int pp;
1916
1917
printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
1918
for (pp = 0; pp < pattrib->pkt_len; pp++)
1919
printk(" %02x ", ptr[pp]);
1920
printk("\n");
1921
}
1922
#endif
1923
1924
precv_frame = decryptor(adapter, precv_frame);
1925
/* save actual management data frame body */
1926
_rtw_memcpy(mgmt_DATA, ptr + pattrib->hdrlen + pattrib->iv_len, data_len);
1927
/* overwrite the iv field */
1928
_rtw_memcpy(ptr + pattrib->hdrlen, mgmt_DATA, data_len);
1929
/* remove the iv and icv length */
1930
pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len;
1931
rtw_mfree(mgmt_DATA, data_len);
1932
1933
#if DBG_VALIDATE_MGMT_DEC
1934
/* print packet content after decryption */
1935
{
1936
int pp;
1937
1938
printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len);
1939
for (pp = 0; pp < pattrib->pkt_len; pp++)
1940
printk(" %02x ", ptr[pp]);
1941
printk("\n");
1942
}
1943
#endif
1944
1945
if (!precv_frame) {
1946
#if DBG_VALIDATE_MGMT_PROTECT
1947
RTW_INFO(FUNC_ADPT_FMT" mgmt descrypt fail !!!!!!!!!\n", FUNC_ADPT_ARG(adapter));
1948
#endif
1949
goto fail;
1950
}
1951
1952
exit:
1953
return _SUCCESS;
1954
1955
fail:
1956
return _FAIL;
1957
1958
}
1959
#endif /* defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH) */
1960
1961
union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame);
1962
1963
sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame)
1964
{
1965
struct sta_info *psta = precv_frame->u.hdr.psta
1966
= rtw_get_stainfo(&padapter->stapriv, get_addr2_ptr(precv_frame->u.hdr.rx_data));
1967
1968
#if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
1969
if (validate_mgmt_protect(padapter, precv_frame) == _FAIL) {
1970
DBG_COUNTER(padapter->rx_logs.core_rx_pre_mgmt_err_80211w);
1971
goto exit;
1972
}
1973
#endif
1974
1975
precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1976
if (precv_frame == NULL)
1977
return _SUCCESS;
1978
1979
/* for rx pkt statistics */
1980
if (psta) {
1981
psta->sta_stats.last_rx_time = rtw_get_current_time();
1982
psta->sta_stats.rx_mgnt_pkts++;
1983
if (get_frame_sub_type(precv_frame->u.hdr.rx_data) == WIFI_BEACON)
1984
psta->sta_stats.rx_beacon_pkts++;
1985
else if (get_frame_sub_type(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ)
1986
psta->sta_stats.rx_probereq_pkts++;
1987
else if (get_frame_sub_type(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
1988
if (_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN) == _TRUE)
1989
psta->sta_stats.rx_probersp_pkts++;
1990
else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))
1991
|| is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
1992
psta->sta_stats.rx_probersp_bm_pkts++;
1993
else
1994
psta->sta_stats.rx_probersp_uo_pkts++;
1995
}
1996
}
1997
1998
mgt_dispatcher(padapter, precv_frame);
1999
2000
#if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
2001
exit:
2002
#endif
2003
return _SUCCESS;
2004
2005
}
2006
2007
sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame)
2008
{
2009
u8 bretry, a4_shift;
2010
struct sta_info *psta = NULL;
2011
u8 *ptr = precv_frame->u.hdr.rx_data;
2012
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2013
struct security_priv *psecuritypriv = &adapter->securitypriv;
2014
sint ret = _SUCCESS;
2015
2016
bretry = GetRetry(ptr);
2017
a4_shift = (pattrib->to_fr_ds == 3) ? ETH_ALEN : 0;
2018
2019
/* some address fields are different when using AMSDU */
2020
if (pattrib->qos)
2021
pattrib->amsdu = GetAMsdu(ptr + WLAN_HDR_A3_LEN + a4_shift);
2022
else
2023
pattrib->amsdu = 0;
2024
2025
#ifdef CONFIG_RTW_MESH
2026
if (MLME_IS_MESH(adapter)) {
2027
ret = rtw_mesh_rx_data_validate_hdr(adapter, precv_frame, &psta);
2028
goto pre_validate_status_chk;
2029
}
2030
#endif
2031
2032
switch (pattrib->to_fr_ds) {
2033
case 0:
2034
_rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2035
_rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2036
_rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
2037
_rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
2038
_rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
2039
ret = sta2sta_data_frame(adapter, precv_frame, &psta);
2040
break;
2041
2042
case 1:
2043
_rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2044
_rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2045
_rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
2046
_rtw_memcpy(pattrib->src, GetAddr3Ptr(ptr), ETH_ALEN);
2047
_rtw_memcpy(pattrib->bssid, get_addr2_ptr(ptr), ETH_ALEN);
2048
ret = ap2sta_data_frame(adapter, precv_frame, &psta);
2049
break;
2050
2051
case 2:
2052
_rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2053
_rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2054
_rtw_memcpy(pattrib->dst, GetAddr3Ptr(ptr), ETH_ALEN);
2055
_rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
2056
_rtw_memcpy(pattrib->bssid, GetAddr1Ptr(ptr), ETH_ALEN);
2057
ret = sta2ap_data_frame(adapter, precv_frame, &psta);
2058
break;
2059
2060
case 3:
2061
default:
2062
/* WDS is not supported */
2063
ret = _FAIL;
2064
break;
2065
}
2066
2067
#ifdef CONFIG_RTW_MESH
2068
pre_validate_status_chk:
2069
#endif
2070
if (ret == _FAIL) {
2071
#ifdef DBG_RX_DROP_FRAME
2072
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" case:%d, res:%d, ra="MAC_FMT", ta="MAC_FMT"\n"
2073
, FUNC_ADPT_ARG(adapter), pattrib->to_fr_ds, ret, MAC_ARG(GetAddr1Ptr(ptr)), MAC_ARG(get_addr2_ptr(ptr)));
2074
#endif
2075
goto exit;
2076
} else if (ret == RTW_RX_HANDLED)
2077
goto exit;
2078
2079
2080
if (psta == NULL) {
2081
#ifdef DBG_RX_DROP_FRAME
2082
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" psta == NULL, ra="MAC_FMT", ta="MAC_FMT"\n"
2083
, FUNC_ADPT_ARG(adapter), MAC_ARG(GetAddr1Ptr(ptr)), MAC_ARG(get_addr2_ptr(ptr)));
2084
#endif
2085
ret = _FAIL;
2086
goto exit;
2087
}
2088
2089
precv_frame->u.hdr.psta = psta;
2090
precv_frame->u.hdr.preorder_ctrl = NULL;
2091
pattrib->ack_policy = 0;
2092
2093
/* parsing QC field */
2094
if (pattrib->qos == 1) {
2095
pattrib->priority = GetPriority((ptr + WLAN_HDR_A3_LEN + a4_shift)); /* point to Qos field*/
2096
pattrib->ack_policy = GetAckpolicy((ptr + WLAN_HDR_A3_LEN + a4_shift));
2097
pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN + a4_shift;
2098
if (pattrib->priority != 0 && pattrib->priority != 3)
2099
adapter->recvpriv.is_any_non_be_pkts = _TRUE;
2100
else
2101
adapter->recvpriv.is_any_non_be_pkts = _FALSE;
2102
} else {
2103
pattrib->priority = 0;
2104
pattrib->hdrlen = WLAN_HDR_A3_LEN + a4_shift;
2105
}
2106
2107
if (pattrib->order) /* HT-CTRL 11n */
2108
pattrib->hdrlen += 4;
2109
2110
/* decache, drop duplicate recv packets */
2111
ret = recv_decache(precv_frame);
2112
if (ret == _FAIL)
2113
goto exit;
2114
2115
if (!IS_MCAST(pattrib->ra)) {
2116
2117
if (pattrib->qos)
2118
precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
2119
2120
if (recv_ucast_pn_decache(precv_frame) == _FAIL) {
2121
#ifdef DBG_RX_DROP_FRAME
2122
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv_ucast_pn_decache return _FAIL for sta="MAC_FMT"\n"
2123
, FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr));
2124
#endif
2125
ret = _FAIL;
2126
goto exit;
2127
}
2128
} else {
2129
if (recv_bcast_pn_decache(precv_frame) == _FAIL) {
2130
#ifdef DBG_RX_DROP_FRAME
2131
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv_bcast_pn_decache return _FAIL for sta="MAC_FMT"\n"
2132
, FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr));
2133
#endif
2134
ret = _FAIL;
2135
goto exit;
2136
}
2137
}
2138
2139
if (pattrib->privacy) {
2140
#ifdef CONFIG_TDLS
2141
if ((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy == _AES_))
2142
pattrib->encrypt = psta->dot118021XPrivacy;
2143
else
2144
#endif /* CONFIG_TDLS */
2145
GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
2146
2147
2148
SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
2149
} else {
2150
pattrib->encrypt = 0;
2151
pattrib->iv_len = pattrib->icv_len = 0;
2152
}
2153
2154
#ifdef CONFIG_RTW_MESH
2155
if (!pattrib->amsdu
2156
&& pattrib->mesh_ctrl_present
2157
&& (!pattrib->encrypt || pattrib->bdecrypted))
2158
ret = rtw_mesh_rx_validate_mctrl_non_amsdu(adapter, precv_frame);
2159
#endif
2160
2161
exit:
2162
return ret;
2163
}
2164
2165
static inline void dump_rx_packet(u8 *ptr)
2166
{
2167
int i;
2168
2169
RTW_INFO("#############################\n");
2170
for (i = 0; i < 64; i = i + 8)
2171
RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
2172
*(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
2173
RTW_INFO("#############################\n");
2174
}
2175
2176
sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame);
2177
sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
2178
{
2179
/* shall check frame subtype, to / from ds, da, bssid */
2180
2181
/* then call check if rx seq/frag. duplicated. */
2182
2183
u8 type;
2184
u8 subtype;
2185
sint retval = _SUCCESS;
2186
2187
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2188
struct recv_priv *precvpriv = &adapter->recvpriv;
2189
2190
u8 *ptr = precv_frame->u.hdr.rx_data;
2191
u8 ver = (unsigned char)(*ptr) & 0x3 ;
2192
#ifdef CONFIG_FIND_BEST_CHANNEL
2193
struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
2194
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2195
#endif
2196
2197
#ifdef CONFIG_TDLS
2198
struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
2199
#endif /* CONFIG_TDLS */
2200
#ifdef CONFIG_WAPI_SUPPORT
2201
PRT_WAPI_T pWapiInfo = &adapter->wapiInfo;
2202
struct recv_frame_hdr *phdr = &precv_frame->u.hdr;
2203
u8 wai_pkt = 0;
2204
u16 sc;
2205
u8 external_len = 0;
2206
#endif
2207
2208
2209
#ifdef CONFIG_FIND_BEST_CHANNEL
2210
if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
2211
int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, rtw_get_oper_ch(adapter));
2212
if (ch_set_idx >= 0)
2213
rfctl->channel_set[ch_set_idx].rx_count++;
2214
}
2215
#endif
2216
2217
#ifdef CONFIG_TDLS
2218
if (ptdlsinfo->ch_sensing == 1 && ptdlsinfo->cur_channel != 0)
2219
ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel - 1]++;
2220
#endif /* CONFIG_TDLS */
2221
2222
#ifdef RTK_DMP_PLATFORM
2223
if (0) {
2224
RTW_INFO("++\n");
2225
{
2226
int i;
2227
for (i = 0; i < 64; i = i + 8)
2228
RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr + i),
2229
*(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
2230
2231
}
2232
RTW_INFO("--\n");
2233
}
2234
#endif /* RTK_DMP_PLATFORM */
2235
2236
/* add version chk */
2237
if (ver != 0) {
2238
retval = _FAIL;
2239
DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err);
2240
goto exit;
2241
}
2242
2243
type = GetFrameType(ptr);
2244
subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
2245
2246
pattrib->to_fr_ds = get_tofr_ds(ptr);
2247
2248
pattrib->frag_num = GetFragNum(ptr);
2249
pattrib->seq_num = GetSequence(ptr);
2250
2251
pattrib->pw_save = GetPwrMgt(ptr);
2252
pattrib->mfrag = GetMFrag(ptr);
2253
pattrib->mdata = GetMData(ptr);
2254
pattrib->privacy = GetPrivacy(ptr);
2255
pattrib->order = GetOrder(ptr);
2256
#ifdef CONFIG_WAPI_SUPPORT
2257
sc = (pattrib->seq_num << 4) | pattrib->frag_num;
2258
#endif
2259
2260
#if 1 /* Dump rx packets */
2261
{
2262
u8 bDumpRxPkt = 0;
2263
2264
rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
2265
if (bDumpRxPkt == 1) /* dump all rx packets */
2266
dump_rx_packet(ptr);
2267
else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE))
2268
dump_rx_packet(ptr);
2269
else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE))
2270
dump_rx_packet(ptr);
2271
}
2272
#endif
2273
switch (type) {
2274
case WIFI_MGT_TYPE: /* mgnt */
2275
DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt);
2276
retval = validate_recv_mgnt_frame(adapter, precv_frame);
2277
if (retval == _FAIL) {
2278
DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err);
2279
}
2280
retval = _FAIL; /* only data frame return _SUCCESS */
2281
break;
2282
case WIFI_CTRL_TYPE: /* ctrl */
2283
DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl);
2284
retval = validate_recv_ctrl_frame(adapter, precv_frame);
2285
if (retval == _FAIL) {
2286
DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err);
2287
}
2288
retval = _FAIL; /* only data frame return _SUCCESS */
2289
break;
2290
case WIFI_DATA_TYPE: /* data */
2291
DBG_COUNTER(adapter->rx_logs.core_rx_pre_data);
2292
#ifdef CONFIG_WAPI_SUPPORT
2293
if (pattrib->qos)
2294
external_len = 2;
2295
else
2296
external_len = 0;
2297
2298
wai_pkt = rtw_wapi_is_wai_packet(adapter, ptr);
2299
2300
phdr->bIsWaiPacket = wai_pkt;
2301
2302
if (wai_pkt != 0) {
2303
if (sc != adapter->wapiInfo.wapiSeqnumAndFragNum)
2304
adapter->wapiInfo.wapiSeqnumAndFragNum = sc;
2305
else {
2306
retval = _FAIL;
2307
DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_seq_err);
2308
break;
2309
}
2310
} else {
2311
2312
if (rtw_wapi_drop_for_key_absent(adapter, get_addr2_ptr(ptr))) {
2313
retval = _FAIL;
2314
WAPI_TRACE(WAPI_RX, "drop for key absent for rx\n");
2315
DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_key_err);
2316
break;
2317
}
2318
}
2319
2320
#endif
2321
2322
pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
2323
retval = validate_recv_data_frame(adapter, precv_frame);
2324
if (retval == _FAIL) {
2325
precvpriv->dbg_rx_drop_count++;
2326
DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err);
2327
} else if (retval == _SUCCESS) {
2328
#ifdef DBG_RX_DUMP_EAP
2329
if (!pattrib->encrypt || pattrib->bdecrypted) {
2330
u8 bDumpRxPkt;
2331
u16 eth_type;
2332
2333
/* dump eapol */
2334
rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
2335
/* get ether_type */
2336
_rtw_memcpy(&eth_type, ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + LLC_HEADER_SIZE, 2);
2337
eth_type = ntohs((unsigned short) eth_type);
2338
if ((bDumpRxPkt == 4) && (eth_type == 0x888e))
2339
dump_rx_packet(ptr);
2340
}
2341
#endif
2342
} else
2343
DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled);
2344
break;
2345
default:
2346
DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown);
2347
#ifdef DBG_RX_DROP_FRAME
2348
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" fail! type=0x%x\n"
2349
, FUNC_ADPT_ARG(adapter), type);
2350
#endif
2351
retval = _FAIL;
2352
break;
2353
}
2354
2355
exit:
2356
2357
2358
return retval;
2359
}
2360
2361
2362
/* remove the wlanhdr and add the eth_hdr */
2363
sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
2364
{
2365
sint rmv_len;
2366
u16 eth_type, len;
2367
u8 bsnaphdr;
2368
u8 *psnap_type;
2369
struct ieee80211_snap_hdr *psnap;
2370
2371
sint ret = _SUCCESS;
2372
_adapter *adapter = precvframe->u.hdr.adapter;
2373
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2374
2375
u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
2376
struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
2377
2378
2379
if (pattrib->encrypt)
2380
recvframe_pull_tail(precvframe, pattrib->icv_len);
2381
2382
psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib));
2383
psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + SNAP_SIZE;
2384
/* convert hdr + possible LLC headers into Ethernet header */
2385
/* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
2386
if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
2387
(_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) &&
2388
(_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) ||
2389
/* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
2390
_rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
2391
/* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2392
bsnaphdr = _TRUE;
2393
} else {
2394
/* Leave Ethernet header part of hdr and full payload */
2395
bsnaphdr = _FALSE;
2396
}
2397
2398
rmv_len = pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + (bsnaphdr ? SNAP_SIZE : 0);
2399
len = precvframe->u.hdr.len - rmv_len;
2400
2401
2402
_rtw_memcpy(&eth_type, ptr + rmv_len, 2);
2403
eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
2404
pattrib->eth_type = eth_type;
2405
2406
2407
if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)) {
2408
ptr += rmv_len ;
2409
*ptr = 0x87;
2410
*(ptr + 1) = 0x12;
2411
2412
eth_type = 0x8712;
2413
/* append rx status for mp test packets */
2414
ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
2415
if (!ptr) {
2416
ret = _FAIL;
2417
goto exiting;
2418
}
2419
_rtw_memcpy(ptr, get_rxmem(precvframe), 24);
2420
ptr += 24;
2421
} else {
2422
ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
2423
if (!ptr) {
2424
ret = _FAIL;
2425
goto exiting;
2426
}
2427
}
2428
2429
if (ptr) {
2430
_rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2431
_rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
2432
2433
if (!bsnaphdr) {
2434
len = htons(len);
2435
_rtw_memcpy(ptr + 12, &len, 2);
2436
}
2437
2438
rtw_rframe_set_os_pkt(precvframe);
2439
}
2440
2441
exiting:
2442
return ret;
2443
2444
}
2445
2446
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2447
#ifndef CONFIG_SDIO_RX_COPY
2448
#ifdef PLATFORM_LINUX
2449
static void recvframe_expand_pkt(
2450
PADAPTER padapter,
2451
union recv_frame *prframe)
2452
{
2453
struct recv_frame_hdr *pfhdr;
2454
_pkt *ppkt;
2455
u8 shift_sz;
2456
u32 alloc_sz;
2457
u8 *ptr;
2458
2459
2460
pfhdr = &prframe->u.hdr;
2461
2462
/* 6 is for IP header 8 bytes alignment in QoS packet case. */
2463
if (pfhdr->attrib.qos)
2464
shift_sz = 6;
2465
else
2466
shift_sz = 0;
2467
2468
/* for first fragment packet, need to allocate */
2469
/* (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet */
2470
/* 8 is for skb->data 8 bytes alignment.
2471
* alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); */
2472
alloc_sz = 1664; /* round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment */
2473
2474
/* 3 1. alloc new skb */
2475
/* prepare extra space for 4 bytes alignment */
2476
ppkt = rtw_skb_alloc(alloc_sz);
2477
2478
if (!ppkt)
2479
return; /* no way to expand */
2480
2481
/* 3 2. Prepare new skb to replace & release old skb */
2482
/* force ppkt->data at 8-byte alignment address */
2483
skb_reserve(ppkt, 8 - ((SIZE_PTR)ppkt->data & 7));
2484
/* force ip_hdr at 8-byte alignment address according to shift_sz */
2485
skb_reserve(ppkt, shift_sz);
2486
2487
/* copy data to new pkt */
2488
ptr = skb_put(ppkt, pfhdr->len);
2489
if (ptr)
2490
_rtw_memcpy(ptr, pfhdr->rx_data, pfhdr->len);
2491
2492
rtw_skb_free(pfhdr->pkt);
2493
2494
/* attach new pkt to recvframe */
2495
pfhdr->pkt = ppkt;
2496
pfhdr->rx_head = ppkt->head;
2497
pfhdr->rx_data = ppkt->data;
2498
pfhdr->rx_tail = skb_tail_pointer(ppkt);
2499
pfhdr->rx_end = skb_end_pointer(ppkt);
2500
}
2501
#else /*!= PLATFORM_LINUX*/
2502
#warning "recvframe_expand_pkt not implement, defrag may crash system"
2503
#endif
2504
#endif /*#ifndef CONFIG_SDIO_RX_COPY*/
2505
#endif
2506
2507
/* perform defrag */
2508
union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q);
2509
union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q)
2510
{
2511
_list *plist, *phead;
2512
u8 *data, wlanhdr_offset;
2513
u8 curfragnum;
2514
struct recv_frame_hdr *pfhdr, *pnfhdr;
2515
union recv_frame *prframe, *pnextrframe;
2516
_queue *pfree_recv_queue;
2517
2518
2519
curfragnum = 0;
2520
pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
2521
2522
phead = get_list_head(defrag_q);
2523
plist = get_next(phead);
2524
prframe = LIST_CONTAINOR(plist, union recv_frame, u);
2525
pfhdr = &prframe->u.hdr;
2526
rtw_list_delete(&(prframe->u.list));
2527
2528
if (curfragnum != pfhdr->attrib.frag_num) {
2529
/* the first fragment number must be 0 */
2530
/* free the whole queue */
2531
rtw_free_recvframe(prframe, pfree_recv_queue);
2532
rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2533
2534
return NULL;
2535
}
2536
2537
#if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2538
#ifndef CONFIG_SDIO_RX_COPY
2539
recvframe_expand_pkt(adapter, prframe);
2540
#endif
2541
#endif
2542
2543
curfragnum++;
2544
2545
plist = get_list_head(defrag_q);
2546
2547
plist = get_next(plist);
2548
2549
data = get_recvframe_data(prframe);
2550
2551
while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
2552
pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u);
2553
pnfhdr = &pnextrframe->u.hdr;
2554
2555
2556
/* check the fragment sequence (2nd ~n fragment frame) */
2557
2558
if (curfragnum != pnfhdr->attrib.frag_num) {
2559
/* the fragment number must be increasing (after decache) */
2560
/* release the defrag_q & prframe */
2561
rtw_free_recvframe(prframe, pfree_recv_queue);
2562
rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2563
return NULL;
2564
}
2565
2566
curfragnum++;
2567
2568
/* copy the 2nd~n fragment frame's payload to the first fragment */
2569
/* get the 2nd~last fragment frame's payload */
2570
2571
wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
2572
2573
recvframe_pull(pnextrframe, wlanhdr_offset);
2574
2575
/* append to first fragment frame's tail (if privacy frame, pull the ICV) */
2576
recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
2577
2578
/* memcpy */
2579
_rtw_memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
2580
2581
recvframe_put(prframe, pnfhdr->len);
2582
2583
pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
2584
plist = get_next(plist);
2585
2586
};
2587
2588
/* free the defrag_q queue and return the prframe */
2589
rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2590
2591
2592
2593
return prframe;
2594
}
2595
2596
/* check if need to defrag, if needed queue the frame to defrag_q */
2597
union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame)
2598
{
2599
u8 ismfrag;
2600
u8 fragnum;
2601
u8 *psta_addr;
2602
struct recv_frame_hdr *pfhdr;
2603
struct sta_info *psta;
2604
struct sta_priv *pstapriv;
2605
_list *phead;
2606
union recv_frame *prtnframe = NULL;
2607
_queue *pfree_recv_queue, *pdefrag_q = NULL;
2608
2609
2610
pstapriv = &padapter->stapriv;
2611
2612
pfhdr = &precv_frame->u.hdr;
2613
2614
pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2615
2616
/* need to define struct of wlan header frame ctrl */
2617
ismfrag = pfhdr->attrib.mfrag;
2618
fragnum = pfhdr->attrib.frag_num;
2619
2620
psta_addr = pfhdr->attrib.ta;
2621
psta = rtw_get_stainfo(pstapriv, psta_addr);
2622
if (psta == NULL) {
2623
u8 type = GetFrameType(pfhdr->rx_data);
2624
if (type != WIFI_DATA_TYPE) {
2625
psta = rtw_get_bcmc_stainfo(padapter);
2626
if (psta)
2627
pdefrag_q = &psta->sta_recvpriv.defrag_q;
2628
} else
2629
pdefrag_q = NULL;
2630
} else
2631
pdefrag_q = &psta->sta_recvpriv.defrag_q;
2632
2633
if ((ismfrag == 0) && (fragnum == 0)) {
2634
prtnframe = precv_frame;/* isn't a fragment frame */
2635
}
2636
2637
if (ismfrag == 1) {
2638
/* 0~(n-1) fragment frame */
2639
/* enqueue to defraf_g */
2640
if (pdefrag_q != NULL) {
2641
if (fragnum == 0) {
2642
/* the first fragment */
2643
if (_rtw_queue_empty(pdefrag_q) == _FALSE) {
2644
/* free current defrag_q */
2645
rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
2646
}
2647
}
2648
2649
2650
/* Then enqueue the 0~(n-1) fragment into the defrag_q */
2651
2652
/* _rtw_spinlock(&pdefrag_q->lock); */
2653
phead = get_list_head(pdefrag_q);
2654
rtw_list_insert_tail(&pfhdr->list, phead);
2655
/* _rtw_spinunlock(&pdefrag_q->lock); */
2656
2657
2658
prtnframe = NULL;
2659
2660
} else {
2661
/* can't find this ta's defrag_queue, so free this recv_frame */
2662
rtw_free_recvframe(precv_frame, pfree_recv_queue);
2663
prtnframe = NULL;
2664
}
2665
2666
}
2667
2668
if ((ismfrag == 0) && (fragnum != 0)) {
2669
/* the last fragment frame */
2670
/* enqueue the last fragment */
2671
if (pdefrag_q != NULL) {
2672
/* _rtw_spinlock(&pdefrag_q->lock); */
2673
phead = get_list_head(pdefrag_q);
2674
rtw_list_insert_tail(&pfhdr->list, phead);
2675
/* _rtw_spinunlock(&pdefrag_q->lock); */
2676
2677
/* call recvframe_defrag to defrag */
2678
precv_frame = recvframe_defrag(padapter, pdefrag_q);
2679
prtnframe = precv_frame;
2680
2681
} else {
2682
/* can't find this ta's defrag_queue, so free this recv_frame */
2683
rtw_free_recvframe(precv_frame, pfree_recv_queue);
2684
prtnframe = NULL;
2685
}
2686
2687
}
2688
2689
2690
if ((prtnframe != NULL) && (prtnframe->u.hdr.attrib.privacy)) {
2691
/* after defrag we must check tkip mic code */
2692
if (recvframe_chkmic(padapter, prtnframe) == _FAIL) {
2693
rtw_free_recvframe(prtnframe, pfree_recv_queue);
2694
prtnframe = NULL;
2695
}
2696
}
2697
2698
2699
return prtnframe;
2700
2701
}
2702
2703
static int rtw_recv_indicatepkt_check(union recv_frame *rframe, u8 *ehdr_pos, u32 pkt_len)
2704
{
2705
_adapter *adapter = rframe->u.hdr.adapter;
2706
struct recv_priv *recvpriv = &adapter->recvpriv;
2707
struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos;
2708
#ifdef DBG_IP_R_MONITOR
2709
int i;
2710
struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
2711
struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2712
struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2713
struct wlan_network *cur_network = &(pmlmepriv->cur_network);
2714
#endif/*DBG_IP_R_MONITOR*/
2715
int ret = _FAIL;
2716
2717
#ifdef CONFIG_WAPI_SUPPORT
2718
if (rtw_wapi_check_for_drop(adapter, rframe, ehdr_pos)) {
2719
#ifdef DBG_RX_DROP_FRAME
2720
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" rtw_wapi_check_for_drop\n"
2721
, FUNC_ADPT_ARG(adapter));
2722
#endif
2723
goto exit;
2724
}
2725
#endif
2726
2727
if (rframe->u.hdr.psta)
2728
rtw_st_ctl_rx(rframe->u.hdr.psta, ehdr_pos);
2729
2730
if (ntohs(ehdr->h_proto) == 0x888e)
2731
parsing_eapol_packet(adapter, ehdr_pos + ETH_HLEN, rframe->u.hdr.psta, 0);
2732
#ifdef DBG_ARP_DUMP
2733
else if (ntohs(ehdr->h_proto) == ETH_P_ARP)
2734
dump_arp_pkt(RTW_DBGDUMP, ehdr->h_dest, ehdr->h_source, ehdr_pos + ETH_HLEN, 0);
2735
#endif
2736
2737
if (recvpriv->sink_udpport > 0)
2738
rtw_sink_rtp_seq_dbg(adapter, ehdr_pos);
2739
2740
#ifdef DBG_UDP_PKT_LOSE_11AC
2741
#define PAYLOAD_LEN_LOC_OF_IP_HDR 0x10 /*ethernet payload length location of ip header (DA + SA+eth_type+(version&hdr_len)) */
2742
2743
if (ntohs(ehdr->h_proto) == ETH_P_ARP) {
2744
/* ARP Payload length will be 42bytes or 42+18(tailer)=60bytes*/
2745
if (pkt_len != 42 && pkt_len != 60)
2746
RTW_INFO("Error !!%s,ARP Payload length %u not correct\n" , __func__ , pkt_len);
2747
} else if (ntohs(ehdr->h_proto) == ETH_P_IP) {
2748
if (be16_to_cpu(*((u16 *)(ehdr_pos + PAYLOAD_LEN_LOC_OF_IP_HDR))) != (pkt_len) - ETH_HLEN) {
2749
RTW_INFO("Error !!%s,Payload length not correct\n" , __func__);
2750
RTW_INFO("%s, IP header describe Total length=%u\n" , __func__ , be16_to_cpu(*((u16 *)(ehdr_pos + PAYLOAD_LEN_LOC_OF_IP_HDR))));
2751
RTW_INFO("%s, Pkt real length=%u\n" , __func__ , (pkt_len) - ETH_HLEN);
2752
}
2753
}
2754
#endif
2755
2756
#ifdef DBG_IP_R_MONITOR
2757
#define LEN_ARP_OP_HDR 7 /*ARP OERATION */
2758
if (ntohs(ehdr->h_proto) == ETH_P_ARP) {
2759
2760
if(check_fwstate(pmlmepriv, WIFI_ASOC_STATE) == _TRUE){
2761
if(ehdr_pos[ETHERNET_HEADER_SIZE+LEN_ARP_OP_HDR] == 2) {
2762
2763
RTW_INFO("%s,[DBG_ARP] Rx ARP RSP Packet;SeqNum = %d !\n",
2764
__FUNCTION__, pattrib->seq_num);
2765
2766
dump_arp_pkt(RTW_DBGDUMP, ehdr->h_dest, ehdr->h_source, ehdr_pos + ETH_HLEN, 0);
2767
2768
}
2769
}
2770
}
2771
#endif/*DBG_IP_R_MONITOR*/
2772
2773
#ifdef CONFIG_AUTO_AP_MODE
2774
if (ntohs(ehdr->h_proto) == 0x8899)
2775
rtw_auto_ap_rx_msg_dump(adapter, rframe, ehdr_pos);
2776
#endif
2777
2778
ret = _SUCCESS;
2779
2780
#ifdef CONFIG_WAPI_SUPPORT
2781
exit:
2782
#endif
2783
return ret;
2784
}
2785
2786
#ifdef CONFIG_RTW_MESH
2787
static void recv_free_fwd_resource(_adapter *adapter, struct xmit_frame *fwd_frame, _list *b2u_list)
2788
{
2789
struct xmit_priv *xmitpriv = &adapter->xmitpriv;
2790
2791
if (fwd_frame)
2792
rtw_free_xmitframe(xmitpriv, fwd_frame);
2793
2794
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
2795
if (!rtw_is_list_empty(b2u_list)) {
2796
struct xmit_frame *b2uframe;
2797
_list *list;
2798
2799
list = get_next(b2u_list);
2800
while (rtw_end_of_queue_search(b2u_list, list) == _FALSE) {
2801
b2uframe = LIST_CONTAINOR(list, struct xmit_frame, list);
2802
list = get_next(list);
2803
rtw_list_delete(&b2uframe->list);
2804
rtw_free_xmitframe(xmitpriv, b2uframe);
2805
}
2806
}
2807
#endif
2808
}
2809
2810
static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt
2811
, u8 act, struct xmit_frame *fwd_frame, _list *b2u_list)
2812
{
2813
struct xmit_priv *xmitpriv = &adapter->xmitpriv;
2814
_pkt *fwd_pkt = pkt;
2815
2816
if (act & RTW_RX_MSDU_ACT_INDICATE) {
2817
fwd_pkt = rtw_os_pkt_copy(pkt);
2818
if (!fwd_pkt) {
2819
#ifdef DBG_TX_DROP_FRAME
2820
RTW_INFO("DBG_TX_DROP_FRAME %s rtw_os_pkt_copy fail\n", __func__);
2821
#endif
2822
recv_free_fwd_resource(adapter, fwd_frame, b2u_list);
2823
goto exit;
2824
}
2825
}
2826
2827
#if CONFIG_RTW_MESH_DATA_BMC_TO_UC
2828
if (!rtw_is_list_empty(b2u_list)) {
2829
_list *list = get_next(b2u_list);
2830
struct xmit_frame *b2uframe;
2831
2832
while (rtw_end_of_queue_search(b2u_list, list) == _FALSE) {
2833
b2uframe = LIST_CONTAINOR(list, struct xmit_frame, list);
2834
list = get_next(list);
2835
rtw_list_delete(&b2uframe->list);
2836
2837
if (!fwd_frame && rtw_is_list_empty(b2u_list)) /* the last fwd_pkt */
2838
b2uframe->pkt = fwd_pkt;
2839
else
2840
b2uframe->pkt = rtw_os_pkt_copy(fwd_pkt);
2841
if (!b2uframe->pkt) {
2842
rtw_free_xmitframe(xmitpriv, b2uframe);
2843
continue;
2844
}
2845
2846
rtw_xmit_posthandle(adapter, b2uframe, b2uframe->pkt);
2847
}
2848
}
2849
#endif
2850
2851
if (fwd_frame) {
2852
fwd_frame->pkt = fwd_pkt;
2853
if (rtw_xmit_posthandle(adapter, fwd_frame, fwd_pkt) < 0) {
2854
#ifdef DBG_TX_DROP_FRAME
2855
RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit_posthandle fail\n", __func__);
2856
#endif
2857
xmitpriv->tx_drop++;
2858
}
2859
}
2860
2861
exit:
2862
return;
2863
}
2864
#endif /* CONFIG_RTW_MESH */
2865
2866
int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
2867
{
2868
struct rx_pkt_attrib *rattrib = &prframe->u.hdr.attrib;
2869
int a_len, padding_len;
2870
u16 nSubframe_Length;
2871
u8 nr_subframes, i;
2872
u8 *pdata;
2873
_pkt *sub_pkt, *subframes[MAX_SUBFRAME_COUNT];
2874
struct recv_priv *precvpriv = &padapter->recvpriv;
2875
_queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
2876
const u8 *da, *sa;
2877
int act;
2878
#ifdef CONFIG_RTW_MESH /* TODO: move AP mode forward & b2u logic here */
2879
struct xmit_frame *fwd_frame;
2880
_list b2u_list;
2881
#endif
2882
u8 mctrl_len = 0;
2883
int ret = _SUCCESS;
2884
2885
nr_subframes = 0;
2886
2887
recvframe_pull(prframe, rattrib->hdrlen);
2888
2889
if (rattrib->iv_len > 0)
2890
recvframe_pull(prframe, rattrib->iv_len);
2891
2892
a_len = prframe->u.hdr.len;
2893
pdata = prframe->u.hdr.rx_data;
2894
2895
while (a_len > ETH_HLEN) {
2896
/* Offset 12 denote 2 mac address */
2897
nSubframe_Length = RTW_GET_BE16(pdata + 12);
2898
if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
2899
RTW_INFO("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
2900
break;
2901
}
2902
2903
act = RTW_RX_MSDU_ACT_INDICATE;
2904
2905
#ifdef CONFIG_RTW_MESH
2906
fwd_frame = NULL;
2907
2908
if (MLME_IS_MESH(padapter)) {
2909
u8 *mda = pdata, *msa = pdata + ETH_ALEN;
2910
struct rtw_ieee80211s_hdr *mctrl = (struct rtw_ieee80211s_hdr *)(pdata + ETH_HLEN);
2911
int v_ret;
2912
2913
v_ret = rtw_mesh_rx_data_validate_mctrl(padapter, prframe
2914
, mctrl, mda, msa, &mctrl_len, &da, &sa);
2915
if (v_ret != _SUCCESS)
2916
goto move_to_next;
2917
2918
act = rtw_mesh_rx_msdu_act_check(prframe
2919
, mda, msa, da, sa, mctrl, &fwd_frame, &b2u_list);
2920
} else
2921
#endif
2922
{
2923
da = pdata;
2924
sa = pdata + ETH_ALEN;
2925
}
2926
2927
#ifdef CONFIG_RTW_MESH
2928
if (!act)
2929
goto move_to_next;
2930
#endif
2931
2932
rtw_led_rx_control(padapter, da);
2933
2934
sub_pkt = rtw_os_alloc_msdu_pkt(prframe, da, sa
2935
, pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len);
2936
if (sub_pkt == NULL) {
2937
if (act & RTW_RX_MSDU_ACT_INDICATE) {
2938
#ifdef DBG_RX_DROP_FRAME
2939
RTW_INFO("DBG_RX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__);
2940
#endif
2941
}
2942
#ifdef CONFIG_RTW_MESH
2943
if (act & RTW_RX_MSDU_ACT_FORWARD) {
2944
#ifdef DBG_TX_DROP_FRAME
2945
RTW_INFO("DBG_TX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__);
2946
#endif
2947
recv_free_fwd_resource(padapter, fwd_frame, &b2u_list);
2948
}
2949
#endif
2950
break;
2951
}
2952
2953
#ifdef CONFIG_RTW_MESH
2954
if (act & RTW_RX_MSDU_ACT_FORWARD) {
2955
recv_fwd_pkt_hdl(padapter, sub_pkt, act, fwd_frame, &b2u_list);
2956
if (!(act & RTW_RX_MSDU_ACT_INDICATE))
2957
goto move_to_next;
2958
}
2959
#endif
2960
2961
if (rtw_recv_indicatepkt_check(prframe, rtw_os_pkt_data(sub_pkt), rtw_os_pkt_len(sub_pkt)) == _SUCCESS)
2962
subframes[nr_subframes++] = sub_pkt;
2963
else
2964
rtw_os_pkt_free(sub_pkt);
2965
2966
#ifdef CONFIG_RTW_MESH
2967
move_to_next:
2968
#endif
2969
/* move the data point to data content */
2970
pdata += ETH_HLEN;
2971
a_len -= ETH_HLEN;
2972
2973
if (nr_subframes >= MAX_SUBFRAME_COUNT) {
2974
RTW_WARN("ParseSubframe(): Too many Subframes! Packets dropped!\n");
2975
break;
2976
}
2977
2978
pdata += nSubframe_Length;
2979
a_len -= nSubframe_Length;
2980
if (a_len != 0) {
2981
padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1));
2982
if (padding_len == 4)
2983
padding_len = 0;
2984
2985
if (a_len < padding_len) {
2986
RTW_INFO("ParseSubframe(): a_len < padding_len !\n");
2987
break;
2988
}
2989
pdata += padding_len;
2990
a_len -= padding_len;
2991
}
2992
}
2993
2994
for (i = 0; i < nr_subframes; i++) {
2995
sub_pkt = subframes[i];
2996
2997
/* Indicat the packets to upper layer */
2998
if (sub_pkt)
2999
rtw_os_recv_indicate_pkt(padapter, sub_pkt, prframe);
3000
}
3001
3002
prframe->u.hdr.len = 0;
3003
rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
3004
3005
return ret;
3006
}
3007
3008
static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe)
3009
{
3010
_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3011
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3012
int ret;
3013
3014
if (pattrib->amsdu) {
3015
ret = amsdu_to_msdu(padapter, prframe);
3016
if (ret != _SUCCESS) {
3017
#ifdef DBG_RX_DROP_FRAME
3018
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" amsdu_to_msdu fail\n"
3019
, FUNC_ADPT_ARG(padapter));
3020
#endif
3021
rtw_free_recvframe(prframe, pfree_recv_queue);
3022
goto exit;
3023
}
3024
} else {
3025
int act = RTW_RX_MSDU_ACT_INDICATE;
3026
3027
#ifdef CONFIG_RTW_MESH /* TODO: move AP mode forward & b2u logic here */
3028
struct xmit_frame *fwd_frame = NULL;
3029
_list b2u_list;
3030
3031
if (MLME_IS_MESH(padapter) && pattrib->mesh_ctrl_present) {
3032
act = rtw_mesh_rx_msdu_act_check(prframe
3033
, pattrib->mda, pattrib->msa
3034
, pattrib->dst, pattrib->src
3035
, (struct rtw_ieee80211s_hdr *)(get_recvframe_data(prframe) + pattrib->hdrlen + pattrib->iv_len)
3036
, &fwd_frame, &b2u_list);
3037
}
3038
#endif
3039
3040
#ifdef CONFIG_RTW_MESH
3041
if (!act) {
3042
rtw_free_recvframe(prframe, pfree_recv_queue);
3043
ret = _FAIL;
3044
goto exit;
3045
}
3046
#endif
3047
3048
rtw_led_rx_control(padapter, pattrib->dst);
3049
3050
ret = wlanhdr_to_ethhdr(prframe);
3051
if (ret != _SUCCESS) {
3052
if (act & RTW_RX_MSDU_ACT_INDICATE) {
3053
#ifdef DBG_RX_DROP_FRAME
3054
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" wlanhdr_to_ethhdr: drop pkt\n"
3055
, FUNC_ADPT_ARG(padapter));
3056
#endif
3057
}
3058
#ifdef CONFIG_RTW_MESH
3059
if (act & RTW_RX_MSDU_ACT_FORWARD) {
3060
#ifdef DBG_TX_DROP_FRAME
3061
RTW_INFO("DBG_TX_DROP_FRAME %s wlanhdr_to_ethhdr fail\n", __func__);
3062
#endif
3063
recv_free_fwd_resource(padapter, fwd_frame, &b2u_list);
3064
}
3065
#endif
3066
rtw_free_recvframe(prframe, pfree_recv_queue);
3067
goto exit;
3068
}
3069
3070
#ifdef CONFIG_RTW_MESH
3071
if (act & RTW_RX_MSDU_ACT_FORWARD) {
3072
recv_fwd_pkt_hdl(padapter, prframe->u.hdr.pkt, act, fwd_frame, &b2u_list);
3073
if (!(act & RTW_RX_MSDU_ACT_INDICATE)) {
3074
prframe->u.hdr.pkt = NULL;
3075
rtw_free_recvframe(prframe, pfree_recv_queue);
3076
goto exit;
3077
}
3078
}
3079
#endif
3080
3081
if (!RTW_CANNOT_RUN(padapter)) {
3082
ret = rtw_recv_indicatepkt_check(prframe
3083
, get_recvframe_data(prframe), get_recvframe_len(prframe));
3084
if (ret != _SUCCESS) {
3085
rtw_free_recvframe(prframe, pfree_recv_queue);
3086
goto exit;
3087
}
3088
3089
/* indicate this recv_frame */
3090
ret = rtw_recv_indicatepkt(padapter, prframe);
3091
if (ret != _SUCCESS) {
3092
#ifdef DBG_RX_DROP_FRAME
3093
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" rtw_recv_indicatepkt fail!\n"
3094
, FUNC_ADPT_ARG(padapter));
3095
#endif
3096
goto exit;
3097
}
3098
} else {
3099
#ifdef DBG_RX_DROP_FRAME
3100
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DS:%u SR:%u\n"
3101
, FUNC_ADPT_ARG(padapter)
3102
, rtw_is_drv_stopped(padapter)
3103
, rtw_is_surprise_removed(padapter));
3104
#endif
3105
ret = _SUCCESS; /* don't count as packet drop */
3106
rtw_free_recvframe(prframe, pfree_recv_queue);
3107
}
3108
}
3109
3110
exit:
3111
return ret;
3112
}
3113
3114
#if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
3115
static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
3116
{
3117
PADAPTER padapter = preorder_ctrl->padapter;
3118
struct recv_priv *precvpriv = &padapter->recvpriv;
3119
u8 wsize = preorder_ctrl->wsize_b;
3120
u16 wend;
3121
3122
/* Rx Reorder initialize condition. */
3123
if (preorder_ctrl->indicate_seq == 0xFFFF) {
3124
preorder_ctrl->indicate_seq = seq_num;
3125
#ifdef DBG_RX_SEQ
3126
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_INIT indicate_seq:%d, seq_num:%d\n"
3127
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3128
#endif
3129
}
3130
wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF; /* % 4096; */
3131
3132
/* Drop out the packet which SeqNum is smaller than WinStart */
3133
if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) {
3134
#ifdef DBG_RX_DROP_FRAME
3135
RTW_INFO(FUNC_ADPT_FMT" tid:%u indicate_seq:%d > seq_num:%d\n"
3136
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3137
#endif
3138
return _FALSE;
3139
}
3140
3141
/*
3142
* Sliding window manipulation. Conditions includes:
3143
* 1. Incoming SeqNum is equal to WinStart =>Window shift 1
3144
* 2. Incoming SeqNum is larger than the WinEnd => Window shift N
3145
*/
3146
if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
3147
preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3148
#ifdef DBG_RX_SEQ
3149
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_EQUAL indicate_seq:%d, seq_num:%d\n"
3150
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3151
#endif
3152
3153
} else if (SN_LESS(wend, seq_num)) {
3154
/* boundary situation, when seq_num cross 0xFFF */
3155
if (seq_num >= (wsize - 1))
3156
preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
3157
else
3158
preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
3159
3160
precvpriv->dbg_rx_ampdu_window_shift_cnt++;
3161
#ifdef DBG_RX_SEQ
3162
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_LESS(wend, seq_num) indicate_seq:%d, seq_num:%d\n"
3163
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3164
#endif
3165
}
3166
3167
return _TRUE;
3168
}
3169
3170
static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe)
3171
{
3172
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3173
_queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3174
_list *phead, *plist;
3175
union recv_frame *pnextrframe;
3176
struct rx_pkt_attrib *pnextattrib;
3177
3178
/* DbgPrint("+enqueue_reorder_recvframe()\n"); */
3179
3180
/* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3181
/* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3182
3183
3184
phead = get_list_head(ppending_recvframe_queue);
3185
plist = get_next(phead);
3186
3187
while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
3188
pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
3189
pnextattrib = &pnextrframe->u.hdr.attrib;
3190
3191
if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
3192
plist = get_next(plist);
3193
else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
3194
/* Duplicate entry is found!! Do not insert current entry. */
3195
3196
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3197
3198
return _FALSE;
3199
} else
3200
break;
3201
3202
/* DbgPrint("enqueue_reorder_recvframe():while\n"); */
3203
3204
}
3205
3206
3207
/* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3208
/* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3209
3210
rtw_list_delete(&(prframe->u.hdr.list));
3211
3212
rtw_list_insert_tail(&(prframe->u.hdr.list), plist);
3213
3214
/* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3215
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3216
3217
3218
return _TRUE;
3219
3220
}
3221
3222
static void recv_indicatepkts_pkt_loss_cnt(_adapter *padapter, u64 prev_seq, u64 current_seq)
3223
{
3224
struct recv_priv *precvpriv = &padapter->recvpriv;
3225
3226
if (current_seq < prev_seq) {
3227
precvpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq);
3228
precvpriv->rx_drop += (4096 + current_seq - prev_seq);
3229
} else {
3230
precvpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq);
3231
precvpriv->rx_drop += (current_seq - prev_seq);
3232
}
3233
}
3234
3235
static int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
3236
{
3237
/* _irqL irql; */
3238
_list *phead, *plist;
3239
union recv_frame *prframe;
3240
struct rx_pkt_attrib *pattrib;
3241
/* u8 index = 0; */
3242
int bPktInBuf = _FALSE;
3243
struct recv_priv *precvpriv = &padapter->recvpriv;
3244
_queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3245
3246
DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder);
3247
3248
/* DbgPrint("+recv_indicatepkts_in_order\n"); */
3249
3250
/* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3251
/* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3252
3253
phead = get_list_head(ppending_recvframe_queue);
3254
plist = get_next(phead);
3255
3256
#if 0
3257
/* Check if there is any other indication thread running. */
3258
if (pTS->RxIndicateState == RXTS_INDICATE_PROCESSING)
3259
return;
3260
#endif
3261
3262
/* Handling some condition for forced indicate case. */
3263
if (bforced == _TRUE) {
3264
precvpriv->dbg_rx_ampdu_forced_indicate_count++;
3265
if (rtw_is_list_empty(phead)) {
3266
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3267
/* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3268
return _TRUE;
3269
}
3270
3271
prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3272
pattrib = &prframe->u.hdr.attrib;
3273
3274
#ifdef DBG_RX_SEQ
3275
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u FORCE indicate_seq:%d, seq_num:%d\n"
3276
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pattrib->seq_num);
3277
#endif
3278
recv_indicatepkts_pkt_loss_cnt(padapter, preorder_ctrl->indicate_seq, pattrib->seq_num);
3279
preorder_ctrl->indicate_seq = pattrib->seq_num;
3280
}
3281
3282
/* Prepare indication list and indication. */
3283
/* Check if there is any packet need indicate. */
3284
while (!rtw_is_list_empty(phead)) {
3285
3286
prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3287
pattrib = &prframe->u.hdr.attrib;
3288
3289
if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
3290
3291
#if 0
3292
/* This protect buffer from overflow. */
3293
if (index >= REORDER_WIN_SIZE) {
3294
RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!!\n"));
3295
bPktInBuf = TRUE;
3296
break;
3297
}
3298
#endif
3299
3300
plist = get_next(plist);
3301
rtw_list_delete(&(prframe->u.hdr.list));
3302
3303
if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
3304
preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3305
#ifdef DBG_RX_SEQ
3306
RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_EQUAL indicate_seq:%d, seq_num:%d\n"
3307
, FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pattrib->seq_num);
3308
#endif
3309
}
3310
3311
#if 0
3312
index++;
3313
if (index == 1) {
3314
/* Cancel previous pending timer. */
3315
/* PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer); */
3316
if (bforced != _TRUE) {
3317
/* RTW_INFO("_cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);\n"); */
3318
_cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
3319
}
3320
}
3321
#endif
3322
3323
/* Set this as a lock to make sure that only one thread is indicating packet. */
3324
/* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */
3325
3326
/* Indicate packets */
3327
/* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */
3328
3329
3330
/* indicate this recv_frame */
3331
/* DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num); */
3332
if (recv_process_mpdu(padapter, prframe) != _SUCCESS)
3333
precvpriv->dbg_rx_drop_count++;
3334
3335
/* Update local variables. */
3336
bPktInBuf = _FALSE;
3337
3338
} else {
3339
bPktInBuf = _TRUE;
3340
break;
3341
}
3342
3343
/* DbgPrint("recv_indicatepkts_in_order():while\n"); */
3344
3345
}
3346
3347
/* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3348
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3349
3350
#if 0
3351
/* Release the indication lock and set to new indication step. */
3352
if (bPktInBuf) {
3353
/* Set new pending timer. */
3354
/* pTS->RxIndicateState = RXTS_INDICATE_REORDER; */
3355
/* PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime); */
3356
3357
_set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3358
} else {
3359
/* pTS->RxIndicateState = RXTS_INDICATE_IDLE; */
3360
}
3361
#endif
3362
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3363
3364
/* return _TRUE; */
3365
return bPktInBuf;
3366
3367
}
3368
3369
static int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe)
3370
{
3371
_irqL irql;
3372
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3373
struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
3374
_queue *ppending_recvframe_queue = preorder_ctrl ? &preorder_ctrl->pending_recvframe_queue : NULL;
3375
struct recv_priv *precvpriv = &padapter->recvpriv;
3376
3377
if (!pattrib->qos || !preorder_ctrl || preorder_ctrl->enable == _FALSE)
3378
goto _success_exit;
3379
3380
3381
DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder);
3382
3383
_enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3384
3385
3386
if(rtw_test_and_clear_bit(RTW_RECV_ACK_OR_TIMEOUT, &preorder_ctrl->rec_abba_rsp_ack))
3387
preorder_ctrl->indicate_seq = 0xFFFF;
3388
#ifdef DBG_RX_SEQ
3389
RTW_INFO("DBG_RX_SEQ %s:preorder_ctrl->rec_abba_rsp_ack = %u,indicate_seq = %d\n"
3390
, __func__
3391
, preorder_ctrl->rec_abba_rsp_ack
3392
, preorder_ctrl->indicate_seq);
3393
#endif
3394
3395
/* s2. check if winstart_b(indicate_seq) needs to been updated */
3396
if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
3397
precvpriv->dbg_rx_ampdu_drop_count++;
3398
/* pHTInfo->RxReorderDropCounter++; */
3399
/* ReturnRFDList(Adapter, pRfd); */
3400
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3401
/* return _FAIL; */
3402
3403
#ifdef DBG_RX_DROP_FRAME
3404
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" check_indicate_seq fail\n"
3405
, FUNC_ADPT_ARG(padapter));
3406
#endif
3407
#if 0
3408
rtw_recv_indicatepkt(padapter, prframe);
3409
3410
_exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3411
3412
goto _success_exit;
3413
#else
3414
goto _err_exit;
3415
#endif
3416
}
3417
3418
3419
/* s3. Insert all packet into Reorder Queue to maintain its ordering. */
3420
if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) {
3421
/* DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); */
3422
/* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3423
/* return _FAIL; */
3424
#ifdef DBG_RX_DROP_FRAME
3425
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" enqueue_reorder_recvframe fail\n"
3426
, FUNC_ADPT_ARG(padapter));
3427
#endif
3428
goto _err_exit;
3429
}
3430
3431
3432
/* s4. */
3433
/* Indication process. */
3434
/* After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
3435
/* with the SeqNum smaller than latest WinStart and buffer other packets. */
3436
/* */
3437
/* For Rx Reorder condition: */
3438
/* 1. All packets with SeqNum smaller than WinStart => Indicate */
3439
/* 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
3440
/* */
3441
3442
/* recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE); */
3443
if (recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE) == _TRUE) {
3444
if (!preorder_ctrl->bReorderWaiting) {
3445
preorder_ctrl->bReorderWaiting = _TRUE;
3446
_set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3447
}
3448
_exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3449
} else {
3450
preorder_ctrl->bReorderWaiting = _FALSE;
3451
_exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3452
_cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
3453
}
3454
3455
return RTW_RX_HANDLED;
3456
3457
_success_exit:
3458
3459
return _SUCCESS;
3460
3461
_err_exit:
3462
3463
_exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3464
3465
return _FAIL;
3466
}
3467
3468
3469
void rtw_reordering_ctrl_timeout_handler(void *pcontext)
3470
{
3471
_irqL irql;
3472
struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
3473
_adapter *padapter = NULL;
3474
_queue *ppending_recvframe_queue = NULL;
3475
3476
3477
if (preorder_ctrl == NULL)
3478
return;
3479
3480
padapter = preorder_ctrl->padapter;
3481
if (RTW_CANNOT_RUN(padapter))
3482
return;
3483
3484
ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3485
3486
/* RTW_INFO("+rtw_reordering_ctrl_timeout_handler()=>\n"); */
3487
3488
_enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3489
3490
preorder_ctrl->bReorderWaiting = _FALSE;
3491
3492
if (recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE) == _TRUE)
3493
_set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3494
3495
_exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3496
3497
}
3498
#endif /* defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL) */
3499
3500
static void recv_set_iseq_before_mpdu_process(union recv_frame *rframe, u16 seq_num, const char *caller)
3501
{
3502
#if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
3503
struct recv_reorder_ctrl *reorder_ctrl = rframe->u.hdr.preorder_ctrl;
3504
3505
if (reorder_ctrl) {
3506
reorder_ctrl->indicate_seq = seq_num;
3507
#ifdef DBG_RX_SEQ
3508
RTW_INFO("DBG_RX_SEQ %s("ADPT_FMT")-B tid:%u indicate_seq:%d, seq_num:%d\n"
3509
, caller, ADPT_ARG(reorder_ctrl->padapter)
3510
, reorder_ctrl->tid, reorder_ctrl->indicate_seq, seq_num);
3511
#endif
3512
}
3513
#endif
3514
}
3515
3516
static void recv_set_iseq_after_mpdu_process(union recv_frame *rframe, u16 seq_num, const char *caller)
3517
{
3518
#if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
3519
struct recv_reorder_ctrl *reorder_ctrl = rframe->u.hdr.preorder_ctrl;
3520
3521
if (reorder_ctrl) {
3522
reorder_ctrl->indicate_seq = (reorder_ctrl->indicate_seq + 1) % 4096;
3523
#ifdef DBG_RX_SEQ
3524
RTW_INFO("DBG_RX_SEQ %s("ADPT_FMT")-A tid:%u indicate_seq:%d, seq_num:%d\n"
3525
, caller, ADPT_ARG(reorder_ctrl->padapter)
3526
, reorder_ctrl->tid, reorder_ctrl->indicate_seq, seq_num);
3527
#endif
3528
}
3529
#endif
3530
}
3531
3532
#ifdef CONFIG_MP_INCLUDED
3533
int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
3534
{
3535
int ret = _SUCCESS;
3536
u8 *ptr = precv_frame->u.hdr.rx_data;
3537
u8 type, subtype;
3538
struct mp_priv *pmppriv = &adapter->mppriv;
3539
struct mp_tx *pmptx;
3540
unsigned char *sa , *da, *bs;
3541
struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
3542
u32 i = 0;
3543
u8 rtk_prefix[]={0x52, 0x65, 0x61, 0x6C, 0x4C, 0x6F, 0x76, 0x65, 0x54, 0x65, 0x6B};
3544
u8 *prx_data;
3545
pmptx = &pmppriv->tx;
3546
3547
3548
if (pmppriv->mplink_brx == _FALSE) {
3549
3550
u8 bDumpRxPkt = 0;
3551
type = GetFrameType(ptr);
3552
subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
3553
3554
RTW_INFO("hdr len = %d iv_len=%d \n", pattrib->hdrlen , pattrib->iv_len);
3555
prx_data = ptr + pattrib->hdrlen + pattrib->iv_len;
3556
3557
for (i = 0; i < precv_frame->u.hdr.len; i++) {
3558
if (precv_frame->u.hdr.len < (11 + i))
3559
break;
3560
3561
if (_rtw_memcmp(prx_data + i, (void *)&rtk_prefix, 11) == _FALSE) {
3562
bDumpRxPkt = 0;
3563
RTW_DBG("prx_data = %02X != rtk_prefix[%d] = %02X \n", *(prx_data + i), i , rtk_prefix[i]);
3564
} else {
3565
bDumpRxPkt = 1;
3566
RTW_DBG("prx_data = %02X = rtk_prefix[%d] = %02X \n", *(prx_data + i), i , rtk_prefix[i]);
3567
break;
3568
}
3569
}
3570
3571
if (bDumpRxPkt == 1) { /* dump all rx packets */
3572
int i;
3573
RTW_INFO("############ type:0x%02x subtype:0x%02x #################\n", type, subtype);
3574
3575
for (i = 0; i < precv_frame->u.hdr.len; i = i + 8)
3576
RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
3577
*(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
3578
RTW_INFO("#############################\n");
3579
_rtw_memset(pmppriv->mplink_buf, '\0' , sizeof(pmppriv->mplink_buf));
3580
_rtw_memcpy(pmppriv->mplink_buf, ptr, precv_frame->u.hdr.len);
3581
pmppriv->mplink_rx_len = precv_frame->u.hdr.len;
3582
pmppriv->mplink_brx =_TRUE;
3583
}
3584
}
3585
if (pmppriv->bloopback) {
3586
if (_rtw_memcmp(ptr + 24, pmptx->buf + 24, precv_frame->u.hdr.len - 24) == _FALSE) {
3587
RTW_INFO("Compare payload content Fail !!!\n");
3588
ret = _FAIL;
3589
}
3590
}
3591
if (pmppriv->bSetRxBssid == _TRUE) {
3592
3593
sa = get_addr2_ptr(ptr);
3594
da = GetAddr1Ptr(ptr);
3595
bs = GetAddr3Ptr(ptr);
3596
type = GetFrameType(ptr);
3597
subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
3598
3599
if (_rtw_memcmp(bs, adapter->mppriv.network_macaddr, ETH_ALEN) == _FALSE)
3600
ret = _FAIL;
3601
3602
RTW_DBG("############ type:0x%02x subtype:0x%02x #################\n", type, subtype);
3603
RTW_DBG("A2 sa %02X:%02X:%02X:%02X:%02X:%02X \n", *(sa) , *(sa + 1), *(sa+ 2), *(sa + 3), *(sa + 4), *(sa + 5));
3604
RTW_DBG("A1 da %02X:%02X:%02X:%02X:%02X:%02X \n", *(da) , *(da + 1), *(da+ 2), *(da + 3), *(da + 4), *(da + 5));
3605
RTW_DBG("A3 bs %02X:%02X:%02X:%02X:%02X:%02X \n --------------------------\n", *(bs) , *(bs + 1), *(bs+ 2), *(bs + 3), *(bs + 4), *(bs + 5));
3606
}
3607
3608
if (!adapter->mppriv.bmac_filter)
3609
return ret;
3610
3611
if (_rtw_memcmp(get_addr2_ptr(ptr), adapter->mppriv.mac_filter, ETH_ALEN) == _FALSE)
3612
ret = _FAIL;
3613
3614
return ret;
3615
}
3616
3617
static sint MPwlanhdr_to_ethhdr(union recv_frame *precvframe)
3618
{
3619
sint rmv_len;
3620
u16 eth_type, len;
3621
u8 bsnaphdr;
3622
u8 *psnap_type;
3623
u8 mcastheadermac[] = {0x01, 0x00, 0x5e};
3624
3625
struct ieee80211_snap_hdr *psnap;
3626
3627
sint ret = _SUCCESS;
3628
_adapter *adapter = precvframe->u.hdr.adapter;
3629
3630
u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
3631
struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
3632
3633
3634
if (pattrib->encrypt)
3635
recvframe_pull_tail(precvframe, pattrib->icv_len);
3636
3637
psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
3638
psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
3639
/* convert hdr + possible LLC headers into Ethernet header */
3640
/* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
3641
if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
3642
(_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) &&
3643
(_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) ||
3644
/* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
3645
_rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
3646
/* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
3647
bsnaphdr = _TRUE;
3648
} else {
3649
/* Leave Ethernet header part of hdr and full payload */
3650
bsnaphdr = _FALSE;
3651
}
3652
3653
rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
3654
len = precvframe->u.hdr.len - rmv_len;
3655
3656
3657
_rtw_memcpy(&eth_type, ptr + rmv_len, 2);
3658
eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
3659
pattrib->eth_type = eth_type;
3660
3661
{
3662
ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
3663
}
3664
3665
_rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
3666
_rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
3667
3668
if (!bsnaphdr) {
3669
len = htons(len);
3670
_rtw_memcpy(ptr + 12, &len, 2);
3671
}
3672
3673
3674
len = htons(pattrib->seq_num);
3675
/* RTW_INFO("wlan seq = %d ,seq_num =%x\n",len,pattrib->seq_num); */
3676
_rtw_memcpy(ptr + 12, &len, 2);
3677
if (adapter->mppriv.bRTWSmbCfg == _TRUE) {
3678
/* if(_rtw_memcmp(mcastheadermac, pattrib->dst, 3) == _TRUE) */ /* SimpleConfig Dest. */
3679
/* _rtw_memcpy(ptr+ETH_ALEN, pattrib->bssid, ETH_ALEN); */
3680
3681
if (_rtw_memcmp(mcastheadermac, pattrib->bssid, 3) == _TRUE) /* SimpleConfig Dest. */
3682
_rtw_memcpy(ptr, pattrib->bssid, ETH_ALEN);
3683
3684
}
3685
3686
3687
return ret;
3688
3689
}
3690
3691
3692
int mp_recv_frame(_adapter *padapter, union recv_frame *rframe)
3693
{
3694
int ret = _SUCCESS;
3695
struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
3696
_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3697
#ifdef CONFIG_MP_INCLUDED
3698
struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3699
struct mp_priv *pmppriv = &padapter->mppriv;
3700
#endif /* CONFIG_MP_INCLUDED */
3701
u8 type;
3702
u8 *ptr = rframe->u.hdr.rx_data;
3703
u8 *psa, *pda, *pbssid;
3704
struct sta_info *psta = NULL;
3705
DBG_COUNTER(padapter->rx_logs.core_rx_pre);
3706
3707
if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { /* &&(padapter->mppriv.check_mp_pkt == 0)) */
3708
if (pattrib->crc_err == 1)
3709
padapter->mppriv.rx_crcerrpktcount++;
3710
else {
3711
if (_SUCCESS == validate_mp_recv_frame(padapter, rframe))
3712
padapter->mppriv.rx_pktcount++;
3713
else
3714
padapter->mppriv.rx_pktcount_filter_out++;
3715
}
3716
3717
if (pmppriv->rx_bindicatePkt == _FALSE) {
3718
ret = _FAIL;
3719
rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3720
goto exit;
3721
} else {
3722
type = GetFrameType(ptr);
3723
pattrib->to_fr_ds = get_tofr_ds(ptr);
3724
pattrib->frag_num = GetFragNum(ptr);
3725
pattrib->seq_num = GetSequence(ptr);
3726
pattrib->pw_save = GetPwrMgt(ptr);
3727
pattrib->mfrag = GetMFrag(ptr);
3728
pattrib->mdata = GetMData(ptr);
3729
pattrib->privacy = GetPrivacy(ptr);
3730
pattrib->order = GetOrder(ptr);
3731
3732
if (type == WIFI_DATA_TYPE) {
3733
pda = get_da(ptr);
3734
psa = get_sa(ptr);
3735
pbssid = get_hdr_bssid(ptr);
3736
3737
_rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
3738
_rtw_memcpy(pattrib->src, psa, ETH_ALEN);
3739
_rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
3740
3741
switch (pattrib->to_fr_ds) {
3742
case 0:
3743
_rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
3744
_rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
3745
ret = sta2sta_data_frame(padapter, rframe, &psta);
3746
break;
3747
3748
case 1:
3749
3750
_rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
3751
_rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
3752
ret = ap2sta_data_frame(padapter, rframe, &psta);
3753
3754
break;
3755
3756
case 2:
3757
_rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
3758
_rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
3759
ret = sta2ap_data_frame(padapter, rframe, &psta);
3760
break;
3761
3762
case 3:
3763
_rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
3764
_rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
3765
ret = _FAIL;
3766
break;
3767
3768
default:
3769
ret = _FAIL;
3770
break;
3771
}
3772
3773
ret = MPwlanhdr_to_ethhdr(rframe);
3774
3775
if (ret != _SUCCESS) {
3776
#ifdef DBG_RX_DROP_FRAME
3777
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" wlanhdr_to_ethhdr: drop pkt\n"
3778
, FUNC_ADPT_ARG(padapter));
3779
#endif
3780
rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3781
ret = _FAIL;
3782
goto exit;
3783
}
3784
if (!RTW_CANNOT_RUN(padapter)) {
3785
/* indicate this recv_frame */
3786
ret = rtw_recv_indicatepkt(padapter, rframe);
3787
if (ret != _SUCCESS) {
3788
#ifdef DBG_RX_DROP_FRAME
3789
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" rtw_recv_indicatepkt fail!\n"
3790
, FUNC_ADPT_ARG(padapter));
3791
#endif
3792
rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3793
ret = _FAIL;
3794
3795
goto exit;
3796
}
3797
} else {
3798
#ifdef DBG_RX_DROP_FRAME
3799
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
3800
, FUNC_ADPT_ARG(padapter)
3801
, rtw_is_drv_stopped(padapter) ? "True" : "False"
3802
, rtw_is_surprise_removed(padapter) ? "True" : "False");
3803
#endif
3804
ret = _FAIL;
3805
rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3806
goto exit;
3807
}
3808
3809
}
3810
}
3811
3812
}
3813
3814
rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3815
ret = _FAIL;
3816
3817
exit:
3818
return ret;
3819
3820
}
3821
#endif
3822
3823
static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u8 *buf)
3824
{
3825
#define CHAN2FREQ(a) ((a < 14) ? (2407+5*a) : (5000+5*a))
3826
3827
#if 0
3828
#define RTW_RX_RADIOTAP_PRESENT (\
3829
(1 << IEEE80211_RADIOTAP_TSFT) | \
3830
(1 << IEEE80211_RADIOTAP_FLAGS) | \
3831
(1 << IEEE80211_RADIOTAP_RATE) | \
3832
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
3833
(0 << IEEE80211_RADIOTAP_FHSS) | \
3834
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
3835
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
3836
(0 << IEEE80211_RADIOTAP_LOCK_QUALITY) | \
3837
(0 << IEEE80211_RADIOTAP_TX_ATTENUATION) | \
3838
(0 << IEEE80211_RADIOTAP_DB_TX_ATTENUATION) | \
3839
(0 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
3840
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
3841
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
3842
(0 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \
3843
(0 << IEEE80211_RADIOTAP_RX_FLAGS) | \
3844
(0 << IEEE80211_RADIOTAP_TX_FLAGS) | \
3845
(0 << IEEE80211_RADIOTAP_RTS_RETRIES) | \
3846
(0 << IEEE80211_RADIOTAP_DATA_RETRIES) | \
3847
(0 << IEEE80211_RADIOTAP_MCS) | \
3848
(0 << IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)| \
3849
(0 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | \
3850
(0 << IEEE80211_RADIOTAP_EXT) | \
3851
0)
3852
3853
/* (0 << IEEE80211_RADIOTAP_AMPDU_STATUS) | \ */
3854
/* (0 << IEEE80211_RADIOTAP_VHT) | \ */
3855
#endif
3856
3857
#ifndef IEEE80211_RADIOTAP_RX_FLAGS
3858
#define IEEE80211_RADIOTAP_RX_FLAGS 14
3859
#endif
3860
3861
#ifndef IEEE80211_RADIOTAP_MCS
3862
#define IEEE80211_RADIOTAP_MCS 19
3863
#endif
3864
#ifndef IEEE80211_RADIOTAP_VHT
3865
#define IEEE80211_RADIOTAP_VHT 21
3866
#endif
3867
3868
#ifndef IEEE80211_RADIOTAP_F_BADFCS
3869
#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */
3870
#endif
3871
3872
sint ret = _SUCCESS;
3873
struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
3874
3875
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3876
3877
u16 tmp_16bit = 0;
3878
3879
u8 data_rate[] = {
3880
2, 4, 11, 22, /* CCK */
3881
12, 18, 24, 36, 48, 72, 96, 108, /* OFDM */
3882
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* HT MCS index */
3883
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3884
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 1 */
3885
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 2 */
3886
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 3 */
3887
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 4 */
3888
};
3889
3890
_pkt *pskb = NULL;
3891
3892
struct ieee80211_radiotap_header *rtap_hdr = NULL;
3893
u8 *ptr = NULL;
3894
3895
u8 hdr_buf[64] = {0};
3896
u16 rt_len = 8;
3897
3898
/* create header */
3899
rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0];
3900
rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
3901
3902
/* tsft */
3903
if (pattrib->tsfl) {
3904
u64 tmp_64bit;
3905
3906
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_TSFT);
3907
tmp_64bit = cpu_to_le64(pattrib->tsfl);
3908
memcpy(&hdr_buf[rt_len], &tmp_64bit, 8);
3909
rt_len += 8;
3910
}
3911
3912
/* flags */
3913
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS);
3914
if (0)
3915
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_CFP;
3916
3917
if (0)
3918
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_SHORTPRE;
3919
3920
if ((pattrib->encrypt == 1) || (pattrib->encrypt == 5))
3921
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_WEP;
3922
3923
if (pattrib->mfrag)
3924
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FRAG;
3925
3926
/* always append FCS */
3927
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS;
3928
3929
if (0)
3930
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_DATAPAD;
3931
3932
if (pattrib->crc_err)
3933
hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_BADFCS;
3934
3935
if (pattrib->sgi) {
3936
/* Currently unspecified but used */
3937
hdr_buf[rt_len] |= 0x80;
3938
}
3939
rt_len += 1;
3940
3941
/* rate */
3942
if (pattrib->data_rate <= DESC_RATE54M) {
3943
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE);
3944
if (pattrib->data_rate <= DESC_RATE11M) {
3945
/* CCK */
3946
hdr_buf[rt_len] = data_rate[pattrib->data_rate];
3947
} else {
3948
/* OFDM */
3949
hdr_buf[rt_len] = data_rate[pattrib->data_rate];
3950
}
3951
}
3952
rt_len += 1; /* force padding 1 byte for aligned */
3953
3954
/* channel */
3955
tmp_16bit = 0;
3956
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
3957
tmp_16bit = CHAN2FREQ(rtw_get_oper_ch(padapter));
3958
/*tmp_16bit = CHAN2FREQ(pHalData->current_channel);*/
3959
memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
3960
rt_len += 2;
3961
3962
/* channel flags */
3963
// tmp_16bit = 0;
3964
// if (pHalData->current_band_type == BAND_ON_2_4G)
3965
// tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_2GHZ);
3966
// else /*BAND_ON_5G*/
3967
// tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_5GHZ);
3968
// NOTE: tmp_16bit currently contains channel freq; we overwrite the value
3969
// to reflect channel flags.
3970
if (pHalData->current_band_type == BAND_ON_2_4G){
3971
tmp_16bit = cpu_to_le16(IEEE80211_CHAN_2GHZ);
3972
}
3973
else if (pHalData->current_band_type == BAND_ON_5G)
3974
tmp_16bit = cpu_to_le16(IEEE80211_CHAN_5GHZ);
3975
else { // BAND_ON_BOTH; decide based on frequency
3976
if (tmp_16bit >= 5000) {
3977
tmp_16bit = cpu_to_le16(IEEE80211_CHAN_5GHZ);
3978
} else {
3979
tmp_16bit = cpu_to_le16(IEEE80211_CHAN_2GHZ);
3980
}
3981
}
3982
3983
if (pattrib->data_rate <= DESC_RATE54M) {
3984
if (pattrib->data_rate <= DESC_RATE11M) {
3985
/* CCK */
3986
tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_CCK);
3987
} else {
3988
/* OFDM */
3989
tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_OFDM);
3990
}
3991
} else
3992
tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_DYN);
3993
memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
3994
rt_len += 2;
3995
3996
/* dBm Antenna Signal */
3997
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
3998
hdr_buf[rt_len] = pattrib->phy_info.recv_signal_power;
3999
rt_len += 1;
4000
4001
#if 0
4002
/* dBm Antenna Noise */
4003
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
4004
hdr_buf[rt_len] = 0;
4005
rt_len += 1;
4006
4007
/* Signal Quality */
4008
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_LOCK_QUALITY);
4009
hdr_buf[rt_len] = pattrib->phy_info.signal_quality;
4010
rt_len += 1;
4011
#endif
4012
4013
/* Antenna */
4014
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA);
4015
hdr_buf[rt_len] = 0; /* pHalData->rf_type; */
4016
rt_len += 1;
4017
4018
/* RX flags */
4019
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RX_FLAGS);
4020
#if 0
4021
tmp_16bit = cpu_to_le16(0);
4022
memcpy(ptr, &tmp_16bit, 1);
4023
#endif
4024
rt_len += 2;
4025
4026
/* MCS information */
4027
if (pattrib->data_rate >= DESC_RATEMCS0 && pattrib->data_rate <= DESC_RATEMCS31) {
4028
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS);
4029
/* known, flag */
4030
hdr_buf[rt_len] |= BIT1; /* MCS index known */
4031
4032
/* bandwidth */
4033
hdr_buf[rt_len] |= BIT0;
4034
hdr_buf[rt_len + 1] |= (pattrib->bw & 0x03);
4035
4036
/* guard interval */
4037
hdr_buf[rt_len] |= BIT2;
4038
hdr_buf[rt_len + 1] |= (pattrib->sgi & 0x01) << 2;
4039
4040
/* STBC */
4041
hdr_buf[rt_len] |= BIT5;
4042
hdr_buf[rt_len + 1] |= (pattrib->stbc & 0x03) << 5;
4043
4044
rt_len += 2;
4045
4046
/* MCS rate index */
4047
hdr_buf[rt_len] = data_rate[pattrib->data_rate];
4048
rt_len += 1;
4049
}
4050
4051
/* VHT */
4052
if (pattrib->data_rate >= DESC_RATEVHTSS1MCS0 && pattrib->data_rate <= DESC_RATEVHTSS4MCS9) {
4053
rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT);
4054
4055
/* known 16 bit, flag 8 bit */
4056
tmp_16bit = 0;
4057
4058
/* Bandwidth */
4059
tmp_16bit |= BIT6;
4060
4061
/* Group ID */
4062
tmp_16bit |= BIT7;
4063
4064
/* Partial AID */
4065
tmp_16bit |= BIT8;
4066
4067
/* STBC */
4068
tmp_16bit |= BIT0;
4069
hdr_buf[rt_len + 2] |= (pattrib->stbc & 0x01);
4070
4071
/* Guard interval */
4072
tmp_16bit |= BIT2;
4073
hdr_buf[rt_len + 2] |= (pattrib->sgi & 0x01) << 2;
4074
4075
/* LDPC extra OFDM symbol */
4076
tmp_16bit |= BIT4;
4077
hdr_buf[rt_len + 2] |= (pattrib->ldpc & 0x01) << 4;
4078
4079
memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
4080
rt_len += 3;
4081
4082
/* bandwidth */
4083
if (pattrib->bw == 0)
4084
hdr_buf[rt_len] |= 0;
4085
else if (pattrib->bw == 1)
4086
hdr_buf[rt_len] |= 1;
4087
else if (pattrib->bw == 2)
4088
hdr_buf[rt_len] |= 4;
4089
else if (pattrib->bw == 3)
4090
hdr_buf[rt_len] |= 11;
4091
rt_len += 1;
4092
4093
/* mcs_nss */
4094
if (pattrib->data_rate >= DESC_RATEVHTSS1MCS0 && pattrib->data_rate <= DESC_RATEVHTSS1MCS9) {
4095
hdr_buf[rt_len] |= 1;
4096
hdr_buf[rt_len] |= data_rate[pattrib->data_rate] << 4;
4097
} else if (pattrib->data_rate >= DESC_RATEVHTSS2MCS0 && pattrib->data_rate <= DESC_RATEVHTSS2MCS9) {
4098
hdr_buf[rt_len + 1] |= 2;
4099
hdr_buf[rt_len + 1] |= data_rate[pattrib->data_rate] << 4;
4100
} else if (pattrib->data_rate >= DESC_RATEVHTSS3MCS0 && pattrib->data_rate <= DESC_RATEVHTSS3MCS9) {
4101
hdr_buf[rt_len + 2] |= 3;
4102
hdr_buf[rt_len + 2] |= data_rate[pattrib->data_rate] << 4;
4103
} else if (pattrib->data_rate >= DESC_RATEVHTSS4MCS0 && pattrib->data_rate <= DESC_RATEVHTSS4MCS9) {
4104
hdr_buf[rt_len + 3] |= 4;
4105
hdr_buf[rt_len + 3] |= data_rate[pattrib->data_rate] << 4;
4106
}
4107
rt_len += 4;
4108
4109
/* coding */
4110
hdr_buf[rt_len] = 0;
4111
rt_len += 1;
4112
4113
/* group_id */
4114
hdr_buf[rt_len] = 0;
4115
rt_len += 1;
4116
4117
/* partial_aid */
4118
tmp_16bit = 0;
4119
memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
4120
rt_len += 2;
4121
}
4122
4123
/* push to skb */
4124
pskb = (_pkt *)buf;
4125
if (skb_headroom(pskb) < rt_len) {
4126
RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__);
4127
ret = _FAIL;
4128
return ret;
4129
}
4130
4131
ptr = skb_push(pskb, rt_len);
4132
if (ptr) {
4133
rtap_hdr->it_len = cpu_to_le16(rt_len);
4134
rtap_hdr->it_present = cpu_to_le32(rtap_hdr->it_present);
4135
memcpy(ptr, rtap_hdr, rt_len);
4136
} else
4137
ret = _FAIL;
4138
4139
return ret;
4140
4141
}
4142
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
4143
int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe)
4144
{
4145
int ret = _SUCCESS;
4146
_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4147
_pkt *pskb = NULL;
4148
4149
/* read skb information from recv frame */
4150
pskb = rframe->u.hdr.pkt;
4151
pskb->len = rframe->u.hdr.len;
4152
pskb->data = rframe->u.hdr.rx_data;
4153
skb_set_tail_pointer(pskb, rframe->u.hdr.len);
4154
4155
#ifndef CONFIG_CUSTOMER_ALIBABA_GENERAL
4156
/* fill radiotap header */
4157
if (fill_radiotap_hdr(padapter, rframe, (u8 *)pskb) == _FAIL) {
4158
ret = _FAIL;
4159
rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4160
goto exit;
4161
}
4162
#endif
4163
/* write skb information to recv frame */
4164
skb_reset_mac_header(pskb);
4165
rframe->u.hdr.len = pskb->len;
4166
rframe->u.hdr.rx_data = pskb->data;
4167
rframe->u.hdr.rx_head = pskb->head;
4168
rframe->u.hdr.rx_tail = skb_tail_pointer(pskb);
4169
rframe->u.hdr.rx_end = skb_end_pointer(pskb);
4170
4171
if (!RTW_CANNOT_RUN(padapter)) {
4172
/* indicate this recv_frame */
4173
ret = rtw_recv_monitor(padapter, rframe);
4174
if (ret != _SUCCESS) {
4175
ret = _FAIL;
4176
rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4177
goto exit;
4178
}
4179
} else {
4180
ret = _FAIL;
4181
rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4182
goto exit;
4183
}
4184
4185
exit:
4186
return ret;
4187
}
4188
#endif
4189
int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
4190
{
4191
int ret = _SUCCESS;
4192
#ifdef DBG_RX_COUNTER_DUMP
4193
struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
4194
#endif
4195
_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4196
4197
#ifdef DBG_RX_COUNTER_DUMP
4198
if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
4199
if (pattrib->crc_err == 1)
4200
padapter->drv_rx_cnt_crcerror++;
4201
else
4202
padapter->drv_rx_cnt_ok++;
4203
}
4204
#endif
4205
4206
#ifdef CONFIG_MP_INCLUDED
4207
if (padapter->registrypriv.mp_mode == 1 || padapter->mppriv.bRTWSmbCfg == _TRUE) {
4208
mp_recv_frame(padapter, rframe);
4209
ret = _FAIL;
4210
goto exit;
4211
} else
4212
#endif
4213
{
4214
/* check the frame crtl field and decache */
4215
ret = validate_recv_frame(padapter, rframe);
4216
if (ret != _SUCCESS) {
4217
rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
4218
goto exit;
4219
}
4220
}
4221
exit:
4222
return ret;
4223
}
4224
4225
/*#define DBG_RX_BMC_FRAME*/
4226
int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
4227
{
4228
int ret = _SUCCESS;
4229
union recv_frame *orig_prframe = prframe;
4230
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
4231
struct recv_priv *precvpriv = &padapter->recvpriv;
4232
_queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4233
#ifdef CONFIG_TDLS
4234
u8 *psnap_type, *pcategory;
4235
#endif /* CONFIG_TDLS */
4236
4237
DBG_COUNTER(padapter->rx_logs.core_rx_post);
4238
4239
prframe = decryptor(padapter, prframe);
4240
if (prframe == NULL) {
4241
#ifdef DBG_RX_DROP_FRAME
4242
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" decryptor: drop pkt\n"
4243
, FUNC_ADPT_ARG(padapter));
4244
#endif
4245
ret = _FAIL;
4246
DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err);
4247
goto _recv_data_drop;
4248
}
4249
4250
#ifdef DBG_RX_BMC_FRAME
4251
if (IS_MCAST(pattrib->ra))
4252
RTW_INFO("%s =>"ADPT_FMT" Rx BC/MC from "MAC_FMT"\n", __func__, ADPT_ARG(padapter), MAC_ARG(pattrib->ta));
4253
#endif
4254
4255
#if 0
4256
if (is_primary_adapter(padapter)) {
4257
RTW_INFO("+++\n");
4258
{
4259
int i;
4260
u8 *ptr = get_recvframe_data(prframe);
4261
for (i = 0; i < 140; i = i + 8)
4262
RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr + i),
4263
*(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
4264
4265
}
4266
RTW_INFO("---\n");
4267
}
4268
#endif
4269
4270
#ifdef CONFIG_TDLS
4271
/* check TDLS frame */
4272
psnap_type = get_recvframe_data(orig_prframe) + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
4273
pcategory = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
4274
4275
if ((_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, ETH_TYPE_LEN)) &&
4276
((*pcategory == RTW_WLAN_CATEGORY_TDLS) || (*pcategory == RTW_WLAN_CATEGORY_P2P))) {
4277
ret = OnTDLS(padapter, prframe);
4278
if (ret == _FAIL)
4279
goto _exit_recv_func;
4280
}
4281
#endif /* CONFIG_TDLS */
4282
4283
prframe = recvframe_chk_defrag(padapter, prframe);
4284
if (prframe == NULL) {
4285
#ifdef DBG_RX_DROP_FRAME
4286
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recvframe_chk_defrag: drop pkt\n"
4287
, FUNC_ADPT_ARG(padapter));
4288
#endif
4289
DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err);
4290
goto _recv_data_drop;
4291
}
4292
4293
prframe = portctrl(padapter, prframe);
4294
if (prframe == NULL) {
4295
#ifdef DBG_RX_DROP_FRAME
4296
RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" portctrl: drop pkt\n"
4297
, FUNC_ADPT_ARG(padapter));
4298
#endif
4299
ret = _FAIL;
4300
DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err);
4301
goto _recv_data_drop;
4302
}
4303
4304
count_rx_stats(padapter, prframe, NULL);
4305
4306
#ifdef CONFIG_WAPI_SUPPORT
4307
rtw_wapi_update_info(padapter, prframe);
4308
#endif
4309
4310
#if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
4311
/* including perform A-MPDU Rx Ordering Buffer Control */
4312
ret = recv_indicatepkt_reorder(padapter, prframe);
4313
if (ret == _FAIL) {
4314
rtw_free_recvframe(orig_prframe, pfree_recv_queue);
4315
goto _recv_data_drop;
4316
} else if (ret == RTW_RX_HANDLED) /* queued OR indicated in order */
4317
goto _exit_recv_func;
4318
#endif
4319
4320
recv_set_iseq_before_mpdu_process(prframe, pattrib->seq_num, __func__);
4321
ret = recv_process_mpdu(padapter, prframe);
4322
recv_set_iseq_after_mpdu_process(prframe, pattrib->seq_num, __func__);
4323
if (ret == _FAIL)
4324
goto _recv_data_drop;
4325
4326
_exit_recv_func:
4327
return ret;
4328
4329
_recv_data_drop:
4330
precvpriv->dbg_rx_drop_count++;
4331
return ret;
4332
}
4333
4334
int recv_func(_adapter *padapter, union recv_frame *rframe)
4335
{
4336
int ret;
4337
struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
4338
struct recv_priv *recvpriv = &padapter->recvpriv;
4339
struct security_priv *psecuritypriv = &padapter->securitypriv;
4340
struct mlme_priv *mlmepriv = &padapter->mlmepriv;
4341
#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
4342
u8 type;
4343
u8 *ptr = rframe->u.hdr.rx_data;
4344
#endif
4345
if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE)) {
4346
/* monitor mode */
4347
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
4348
recv_frame_monitor(padapter, rframe);
4349
#endif
4350
ret = _SUCCESS;
4351
goto exit;
4352
} else
4353
{}
4354
#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL
4355
type = GetFrameType(ptr);
4356
if ((type == WIFI_DATA_TYPE)&& check_fwstate(mlmepriv, WIFI_STATION_STATE)) {
4357
struct wlan_network *cur_network = &(mlmepriv->cur_network);
4358
if ( _rtw_memcmp(get_addr2_ptr(ptr), cur_network->network.MacAddress, ETH_ALEN)==0) {
4359
recv_frame_monitor(padapter, rframe);
4360
ret = _SUCCESS;
4361
goto exit;
4362
}
4363
}
4364
#endif
4365
/* check if need to handle uc_swdec_pending_queue*/
4366
if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) {
4367
union recv_frame *pending_frame;
4368
int cnt = 0;
4369
4370
while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) {
4371
cnt++;
4372
DBG_COUNTER(padapter->rx_logs.core_rx_dequeue);
4373
recv_func_posthandle(padapter, pending_frame);
4374
}
4375
4376
if (cnt)
4377
RTW_INFO(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n",
4378
FUNC_ADPT_ARG(padapter), cnt);
4379
}
4380
4381
DBG_COUNTER(padapter->rx_logs.core_rx);
4382
ret = recv_func_prehandle(padapter, rframe);
4383
4384
if (ret == _SUCCESS) {
4385
4386
/* check if need to enqueue into uc_swdec_pending_queue*/
4387
if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
4388
!IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 &&
4389
(prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt == _TRUE) &&
4390
psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
4391
!psecuritypriv->busetkipkey) {
4392
DBG_COUNTER(padapter->rx_logs.core_rx_enqueue);
4393
rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
4394
/* RTW_INFO("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); */
4395
4396
if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) {
4397
/* to prevent from recvframe starvation, get recvframe from uc_swdec_pending_queue to free_recvframe_cnt */
4398
rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
4399
if (rframe)
4400
goto do_posthandle;
4401
}
4402
goto exit;
4403
}
4404
4405
do_posthandle:
4406
ret = recv_func_posthandle(padapter, rframe);
4407
}
4408
4409
exit:
4410
return ret;
4411
}
4412
4413
4414
s32 rtw_recv_entry(union recv_frame *precvframe)
4415
{
4416
_adapter *padapter;
4417
struct recv_priv *precvpriv;
4418
s32 ret = _SUCCESS;
4419
4420
4421
4422
padapter = precvframe->u.hdr.adapter;
4423
4424
precvpriv = &padapter->recvpriv;
4425
4426
4427
ret = recv_func(padapter, precvframe);
4428
if (ret == _FAIL) {
4429
goto _recv_entry_drop;
4430
}
4431
4432
4433
precvpriv->rx_pkts++;
4434
4435
4436
return ret;
4437
4438
_recv_entry_drop:
4439
4440
#ifdef CONFIG_MP_INCLUDED
4441
if (padapter->registrypriv.mp_mode == 1)
4442
padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
4443
#endif
4444
4445
4446
4447
return ret;
4448
}
4449
4450
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4451
static void rtw_signal_stat_timer_hdl(void *ctx)
4452
{
4453
_adapter *adapter = (_adapter *)ctx;
4454
struct recv_priv *recvpriv = &adapter->recvpriv;
4455
4456
u32 tmp_s, tmp_q;
4457
u8 avg_signal_strength = 0;
4458
u8 avg_signal_qual = 0;
4459
u32 num_signal_strength = 0;
4460
u32 num_signal_qual = 0;
4461
u8 ratio_pre_stat = 0, ratio_curr_stat = 0, ratio_total = 0, ratio_profile = SIGNAL_STAT_CALC_PROFILE_0;
4462
4463
if (adapter->recvpriv.is_signal_dbg) {
4464
/* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
4465
adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
4466
adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
4467
} else {
4468
4469
if (recvpriv->signal_strength_data.update_req == 0) { /* update_req is clear, means we got rx */
4470
avg_signal_strength = recvpriv->signal_strength_data.avg_val;
4471
num_signal_strength = recvpriv->signal_strength_data.total_num;
4472
/* after avg_vals are accquired, we can re-stat the signal values */
4473
recvpriv->signal_strength_data.update_req = 1;
4474
}
4475
4476
if (recvpriv->signal_qual_data.update_req == 0) { /* update_req is clear, means we got rx */
4477
avg_signal_qual = recvpriv->signal_qual_data.avg_val;
4478
num_signal_qual = recvpriv->signal_qual_data.total_num;
4479
/* after avg_vals are accquired, we can re-stat the signal values */
4480
recvpriv->signal_qual_data.update_req = 1;
4481
}
4482
4483
if (num_signal_strength == 0) {
4484
if (rtw_get_on_cur_ch_time(adapter) == 0
4485
|| rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval
4486
)
4487
goto set_timer;
4488
}
4489
4490
if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE
4491
|| check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE
4492
)
4493
goto set_timer;
4494
4495
#ifdef CONFIG_CONCURRENT_MODE
4496
if (rtw_mi_buddy_check_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE)
4497
goto set_timer;
4498
#endif
4499
4500
if (RTW_SIGNAL_STATE_CALC_PROFILE < SIGNAL_STAT_CALC_PROFILE_MAX)
4501
ratio_profile = RTW_SIGNAL_STATE_CALC_PROFILE;
4502
4503
ratio_pre_stat = signal_stat_calc_profile[ratio_profile][0];
4504
ratio_curr_stat = signal_stat_calc_profile[ratio_profile][1];
4505
ratio_total = ratio_pre_stat + ratio_curr_stat;
4506
4507
/* update value of signal_strength, rssi, signal_qual */
4508
tmp_s = (ratio_curr_stat * avg_signal_strength + ratio_pre_stat * recvpriv->signal_strength);
4509
if (tmp_s % ratio_total)
4510
tmp_s = tmp_s / ratio_total + 1;
4511
else
4512
tmp_s = tmp_s / ratio_total;
4513
if (tmp_s > 100)
4514
tmp_s = 100;
4515
4516
tmp_q = (ratio_curr_stat * avg_signal_qual + ratio_pre_stat * recvpriv->signal_qual);
4517
if (tmp_q % ratio_total)
4518
tmp_q = tmp_q / ratio_total + 1;
4519
else
4520
tmp_q = tmp_q / ratio_total;
4521
if (tmp_q > 100)
4522
tmp_q = 100;
4523
4524
recvpriv->signal_strength = tmp_s;
4525
recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
4526
recvpriv->signal_qual = tmp_q;
4527
4528
#if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
4529
RTW_INFO(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
4530
", num_signal_strength:%u, num_signal_qual:%u"
4531
", on_cur_ch_ms:%d"
4532
"\n"
4533
, FUNC_ADPT_ARG(adapter)
4534
, recvpriv->signal_strength
4535
, recvpriv->rssi
4536
, recvpriv->signal_qual
4537
, num_signal_strength, num_signal_qual
4538
, rtw_get_on_cur_ch_time(adapter) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) : 0
4539
);
4540
#endif
4541
}
4542
4543
set_timer:
4544
rtw_set_signal_stat_timer(recvpriv);
4545
4546
}
4547
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4548
4549
static void rx_process_rssi(_adapter *padapter, union recv_frame *prframe)
4550
{
4551
struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
4552
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4553
struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data;
4554
#else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4555
u32 last_rssi, tmp_val;
4556
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4557
4558
/* RTW_INFO("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->recv_signal_power,pattrib->signal_strength); */
4559
/* if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon) */
4560
{
4561
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4562
if (signal_stat->update_req) {
4563
signal_stat->total_num = 0;
4564
signal_stat->total_val = 0;
4565
signal_stat->update_req = 0;
4566
}
4567
4568
signal_stat->total_num++;
4569
signal_stat->total_val += pattrib->phy_info.signal_strength;
4570
signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
4571
#else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4572
4573
/* Adapter->RxStats.RssiCalculateCnt++; */ /* For antenna Test */
4574
if (padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
4575
padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX;
4576
last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index];
4577
padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
4578
}
4579
padapter->recvpriv.signal_strength_data.total_val += pattrib->phy_info.signal_strength;
4580
4581
padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->phy_info.signal_strength;
4582
if (padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX)
4583
padapter->recvpriv.signal_strength_data.index = 0;
4584
4585
4586
tmp_val = padapter->recvpriv.signal_strength_data.total_val / padapter->recvpriv.signal_strength_data.total_num;
4587
4588
if (padapter->recvpriv.is_signal_dbg) {
4589
padapter->recvpriv.signal_strength = padapter->recvpriv.signal_strength_dbg;
4590
padapter->recvpriv.rssi = (s8)translate_percentage_to_dbm(padapter->recvpriv.signal_strength_dbg);
4591
} else {
4592
padapter->recvpriv.signal_strength = tmp_val;
4593
padapter->recvpriv.rssi = (s8)translate_percentage_to_dbm(tmp_val);
4594
}
4595
4596
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4597
}
4598
}
4599
4600
static void rx_process_link_qual(_adapter *padapter, union recv_frame *prframe)
4601
{
4602
struct rx_pkt_attrib *pattrib;
4603
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4604
struct signal_stat *signal_stat;
4605
#else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4606
u32 last_evm = 0, tmpVal;
4607
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4608
4609
if (prframe == NULL || padapter == NULL)
4610
return;
4611
4612
pattrib = &prframe->u.hdr.attrib;
4613
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4614
signal_stat = &padapter->recvpriv.signal_qual_data;
4615
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4616
4617
/* RTW_INFO("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual); */
4618
4619
#ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4620
if (signal_stat->update_req) {
4621
signal_stat->total_num = 0;
4622
signal_stat->total_val = 0;
4623
signal_stat->update_req = 0;
4624
}
4625
4626
signal_stat->total_num++;
4627
signal_stat->total_val += pattrib->phy_info.signal_quality;
4628
signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
4629
4630
#else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4631
if (pattrib->phy_info.signal_quality != 0) {
4632
/* */
4633
/* 1. Record the general EVM to the sliding window. */
4634
/* */
4635
if (padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) {
4636
padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
4637
last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
4638
padapter->recvpriv.signal_qual_data.total_val -= last_evm;
4639
}
4640
padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.signal_quality;
4641
4642
padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->phy_info.signal_quality;
4643
if (padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
4644
padapter->recvpriv.signal_qual_data.index = 0;
4645
4646
4647
/* <1> Showed on UI for user, in percentage. */
4648
tmpVal = padapter->recvpriv.signal_qual_data.total_val / padapter->recvpriv.signal_qual_data.total_num;
4649
padapter->recvpriv.signal_qual = (u8)tmpVal;
4650
4651
}
4652
#endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4653
}
4654
4655
void rx_process_phy_info(_adapter *padapter, union recv_frame *rframe)
4656
{
4657
/* Check RSSI */
4658
rx_process_rssi(padapter, rframe);
4659
4660
/* Check PWDB */
4661
/* process_PWDB(padapter, rframe); */
4662
4663
/* UpdateRxSignalStatistics8192C(Adapter, pRfd); */
4664
4665
/* Check EVM */
4666
rx_process_link_qual(padapter, rframe);
4667
rtw_store_phy_info(padapter, rframe);
4668
}
4669
4670
void rx_query_phy_status(
4671
union recv_frame *precvframe,
4672
u8 *pphy_status)
4673
{
4674
PADAPTER padapter = precvframe->u.hdr.adapter;
4675
struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
4676
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4677
struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
4678
u8 *wlanhdr;
4679
struct phydm_perpkt_info_struct pkt_info;
4680
u8 *ta, *ra;
4681
u8 is_ra_bmc;
4682
struct sta_priv *pstapriv;
4683
struct sta_info *psta = NULL;
4684
struct recv_priv *precvpriv = &padapter->recvpriv;
4685
/* _irqL irqL; */
4686
4687
pkt_info.is_packet_match_bssid = _FALSE;
4688
pkt_info.is_packet_to_self = _FALSE;
4689
pkt_info.is_packet_beacon = _FALSE;
4690
pkt_info.ppdu_cnt = pattrib->ppdu_cnt;
4691
pkt_info.station_id = 0xFF;
4692
4693
wlanhdr = get_recvframe_data(precvframe);
4694
4695
ta = get_ta(wlanhdr);
4696
ra = get_ra(wlanhdr);
4697
is_ra_bmc = IS_MCAST(ra);
4698
4699
if (_rtw_memcmp(adapter_mac_addr(padapter), ta, ETH_ALEN) == _TRUE) {
4700
static systime start_time = 0;
4701
4702
#if 0 /*For debug */
4703
if (IsFrameTypeCtrl(wlanhdr)) {
4704
RTW_INFO("-->Control frame: Y\n");
4705
RTW_INFO("-->pkt_len: %d\n", pattrib->pkt_len);
4706
RTW_INFO("-->Sub Type = 0x%X\n", get_frame_sub_type(wlanhdr));
4707
}
4708
4709
/* Dump first 40 bytes of header */
4710
int i = 0;
4711
4712
for (i = 0; i < 40; i++)
4713
RTW_INFO("%d: %X\n", i, *((u8 *)wlanhdr + i));
4714
4715
RTW_INFO("\n");
4716
#endif
4717
4718
if ((start_time == 0) || (rtw_get_passing_time_ms(start_time) > 5000)) {
4719
RTW_PRINT("Warning!!! %s: Confilc mac addr!!\n", __func__);
4720
start_time = rtw_get_current_time();
4721
}
4722
precvpriv->dbg_rx_conflic_mac_addr_cnt++;
4723
} else {
4724
pstapriv = &padapter->stapriv;
4725
psta = rtw_get_stainfo(pstapriv, ta);
4726
if (psta)
4727
pkt_info.station_id = psta->cmn.mac_id;
4728
}
4729
4730
pkt_info.is_packet_match_bssid = (!IsFrameTypeCtrl(wlanhdr))
4731
&& (!pattrib->icv_err) && (!pattrib->crc_err)
4732
&& ((!MLME_IS_MESH(padapter) && _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN))
4733
|| (MLME_IS_MESH(padapter) && psta));
4734
4735
pkt_info.is_to_self = (!pattrib->icv_err) && (!pattrib->crc_err)
4736
&& _rtw_memcmp(ra, adapter_mac_addr(padapter), ETH_ALEN);
4737
4738
pkt_info.is_packet_to_self = pkt_info.is_packet_match_bssid
4739
&& _rtw_memcmp(ra, adapter_mac_addr(padapter), ETH_ALEN);
4740
4741
pkt_info.is_packet_beacon = pkt_info.is_packet_match_bssid
4742
&& (get_frame_sub_type(wlanhdr) == WIFI_BEACON);
4743
4744
if (psta && IsFrameTypeData(wlanhdr)) {
4745
if (is_ra_bmc)
4746
psta->curr_rx_rate_bmc = pattrib->data_rate;
4747
else
4748
psta->curr_rx_rate = pattrib->data_rate;
4749
}
4750
pkt_info.data_rate = pattrib->data_rate;
4751
4752
odm_phy_status_query(&pHalData->odmpriv, p_phy_info, pphy_status, &pkt_info);
4753
4754
/* If bw is initial value, get from phy status */
4755
if (pattrib->bw == CHANNEL_WIDTH_MAX)
4756
pattrib->bw = p_phy_info->band_width;
4757
4758
{
4759
precvframe->u.hdr.psta = NULL;
4760
if (padapter->registrypriv.mp_mode != 1) {
4761
if ((!MLME_IS_MESH(padapter) && pkt_info.is_packet_match_bssid)
4762
|| (MLME_IS_MESH(padapter) && psta)) {
4763
if (psta) {
4764
precvframe->u.hdr.psta = psta;
4765
rx_process_phy_info(padapter, precvframe);
4766
}
4767
} else if (pkt_info.is_packet_to_self || pkt_info.is_packet_beacon) {
4768
if (psta)
4769
precvframe->u.hdr.psta = psta;
4770
rx_process_phy_info(padapter, precvframe);
4771
}
4772
} else {
4773
#ifdef CONFIG_MP_INCLUDED
4774
if (padapter->mppriv.brx_filter_beacon == _TRUE) {
4775
if (pkt_info.is_packet_beacon) {
4776
RTW_INFO("in MP Rx is_packet_beacon\n");
4777
if (psta)
4778
precvframe->u.hdr.psta = psta;
4779
rx_process_phy_info(padapter, precvframe);
4780
}
4781
} else
4782
#endif
4783
{
4784
if (psta)
4785
precvframe->u.hdr.psta = psta;
4786
rx_process_phy_info(padapter, precvframe);
4787
}
4788
}
4789
}
4790
4791
rtw_odm_parse_rx_phy_status_chinfo(precvframe, pphy_status);
4792
}
4793
/*
4794
* Increase and check if the continual_no_rx_packet of this @param pmlmepriv is larger than MAX_CONTINUAL_NORXPACKET_COUNT
4795
* @return _TRUE:
4796
* @return _FALSE:
4797
*/
4798
int rtw_inc_and_chk_continual_no_rx_packet(struct sta_info *sta, int tid_index)
4799
{
4800
4801
int ret = _FALSE;
4802
int value = ATOMIC_INC_RETURN(&sta->continual_no_rx_packet[tid_index]);
4803
4804
if (value >= MAX_CONTINUAL_NORXPACKET_COUNT)
4805
ret = _TRUE;
4806
4807
return ret;
4808
}
4809
4810
/*
4811
* Set the continual_no_rx_packet of this @param pmlmepriv to 0
4812
*/
4813
void rtw_reset_continual_no_rx_packet(struct sta_info *sta, int tid_index)
4814
{
4815
ATOMIC_SET(&sta->continual_no_rx_packet[tid_index], 0);
4816
}
4817
4818
u8 adapter_allow_bmc_data_rx(_adapter *adapter)
4819
{
4820
if (check_fwstate(&adapter->mlmepriv, WIFI_MONITOR_STATE | WIFI_MP_STATE) == _TRUE)
4821
return 1;
4822
4823
if (MLME_IS_AP(adapter))
4824
return 0;
4825
4826
if (rtw_linked_check(adapter) == _FALSE)
4827
return 0;
4828
4829
return 1;
4830
}
4831
4832
s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status)
4833
{
4834
s32 ret = _SUCCESS;
4835
u8 *pbuf = precvframe->u.hdr.rx_data;
4836
u8 *pda = get_ra(pbuf);
4837
u8 ra_is_bmc = IS_MCAST(pda);
4838
_adapter *primary_padapter = precvframe->u.hdr.adapter;
4839
#ifdef CONFIG_CONCURRENT_MODE
4840
_adapter *iface = NULL;
4841
4842
#ifdef CONFIG_MP_INCLUDED
4843
if (rtw_mp_mode_check(primary_padapter))
4844
goto bypass_concurrent_hdl;
4845
#endif
4846
4847
if (ra_is_bmc == _FALSE) { /*unicast packets*/
4848
iface = rtw_get_iface_by_macddr(primary_padapter , pda);
4849
if (NULL == iface) {
4850
#ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
4851
if (_rtw_memcmp(pda, adapter_pno_mac_addr(primary_padapter),
4852
ETH_ALEN) != _TRUE)
4853
#endif
4854
RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n", __func__, MAC_ARG(pda));
4855
/*rtw_warn_on(1);*/
4856
} else
4857
precvframe->u.hdr.adapter = iface;
4858
} else /* Handle BC/MC Packets */
4859
rtw_mi_buddy_clone_bcmc_packet(primary_padapter, precvframe, pphy_status);
4860
bypass_concurrent_hdl:
4861
#endif /* CONFIG_CONCURRENT_MODE */
4862
if (primary_padapter->registrypriv.mp_mode != 1) {
4863
/* skip unnecessary bmc data frame for primary adapter */
4864
if (ra_is_bmc == _TRUE && GetFrameType(pbuf) == WIFI_DATA_TYPE
4865
&& !adapter_allow_bmc_data_rx(precvframe->u.hdr.adapter)
4866
) {
4867
rtw_free_recvframe(precvframe, &precvframe->u.hdr.adapter->recvpriv.free_recv_queue);
4868
goto exit;
4869
}
4870
}
4871
4872
if (pphy_status)
4873
rx_query_phy_status(precvframe, pphy_status);
4874
ret = rtw_recv_entry(precvframe);
4875
4876
exit:
4877
return ret;
4878
}
4879
4880
#ifdef CONFIG_RECV_THREAD_MODE
4881
thread_return rtw_recv_thread(thread_context context)
4882
{
4883
_adapter *adapter = (_adapter *)context;
4884
struct recv_priv *recvpriv = &adapter->recvpriv;
4885
s32 err = _SUCCESS;
4886
#ifdef RTW_RECV_THREAD_HIGH_PRIORITY
4887
#ifdef PLATFORM_LINUX
4888
struct sched_param param = { .sched_priority = 1 };
4889
4890
sched_setscheduler(current, SCHED_FIFO, &param);
4891
#endif /* PLATFORM_LINUX */
4892
#endif /*RTW_RECV_THREAD_HIGH_PRIORITY*/
4893
thread_enter("RTW_RECV_THREAD");
4894
4895
RTW_INFO(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
4896
4897
do {
4898
err = _rtw_down_sema(&recvpriv->recv_sema);
4899
if (_FAIL == err) {
4900
RTW_ERR(FUNC_ADPT_FMT" down recv_sema fail!\n", FUNC_ADPT_ARG(adapter));
4901
goto exit;
4902
}
4903
4904
if (RTW_CANNOT_RUN(adapter)) {
4905
RTW_DBG(FUNC_ADPT_FMT "- bDriverStopped(%s) bSurpriseRemoved(%s)\n",
4906
FUNC_ADPT_ARG(adapter),
4907
rtw_is_drv_stopped(adapter) ? "True" : "False",
4908
rtw_is_surprise_removed(adapter) ? "True" : "False");
4909
goto exit;
4910
}
4911
4912
err = rtw_hal_recv_hdl(adapter);
4913
4914
if (err == RTW_RFRAME_UNAVAIL
4915
|| err == RTW_RFRAME_PKT_UNAVAIL
4916
) {
4917
rtw_msleep_os(1);
4918
_rtw_up_sema(&recvpriv->recv_sema);
4919
}
4920
4921
flush_signals_thread();
4922
4923
} while (err != _FAIL);
4924
4925
exit:
4926
4927
RTW_INFO(FUNC_ADPT_FMT " Exit\n", FUNC_ADPT_ARG(adapter));
4928
4929
rtw_thread_wait_stop();
4930
4931
return 0;
4932
}
4933
#endif /* CONFIG_RECV_THREAD_MODE */
4934
4935
#if DBG_RX_BH_TRACKING
4936
void rx_bh_tk_set_stage(struct recv_priv *recv, u32 s)
4937
{
4938
recv->rx_bh_stage = s;
4939
}
4940
4941
void rx_bh_tk_set_buf(struct recv_priv *recv, void *buf, void *data, u32 dlen)
4942
{
4943
if (recv->rx_bh_cbuf)
4944
recv->rx_bh_lbuf = recv->rx_bh_cbuf;
4945
recv->rx_bh_cbuf = buf;
4946
if (buf) {
4947
recv->rx_bh_cbuf_data = data;
4948
recv->rx_bh_cbuf_dlen = dlen;
4949
recv->rx_bh_buf_dq_cnt++;
4950
} else {
4951
recv->rx_bh_cbuf_data = NULL;
4952
recv->rx_bh_cbuf_dlen = 0;
4953
}
4954
}
4955
4956
void rx_bh_tk_set_buf_pos(struct recv_priv *recv, void *pos)
4957
{
4958
if (recv->rx_bh_cbuf) {
4959
recv->rx_bh_cbuf_pos = pos - recv->rx_bh_cbuf_data;
4960
} else {
4961
rtw_warn_on(1);
4962
recv->rx_bh_cbuf_pos = 0;
4963
}
4964
}
4965
4966
void rx_bh_tk_set_frame(struct recv_priv *recv, void *frame)
4967
{
4968
recv->rx_bh_cframe = frame;
4969
}
4970
4971
void dump_rx_bh_tk(void *sel, struct recv_priv *recv)
4972
{
4973
RTW_PRINT_SEL(sel, "[RXBHTK]s:%u, buf_dqc:%u, lbuf:%p, cbuf:%p, dlen:%u, pos:%u, cframe:%p\n"
4974
, recv->rx_bh_stage
4975
, recv->rx_bh_buf_dq_cnt
4976
, recv->rx_bh_lbuf
4977
, recv->rx_bh_cbuf
4978
, recv->rx_bh_cbuf_dlen
4979
, recv->rx_bh_cbuf_pos
4980
, recv->rx_bh_cframe
4981
);
4982
}
4983
#endif /* DBG_RX_BH_TRACKING */
4984
4985
4986