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