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