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