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