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