OSDN Git Service

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