OSDN Git Service

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