GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / staging / rtl8723bs / core / rtw_recv.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5  *
6  ******************************************************************************/
7 #define _RTW_RECV_C_
8
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <linux/jiffies.h>
12 #include <rtw_recv.h>
13 #include <net/cfg80211.h>
14 #include <asm/unaligned.h>
15
16 static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
17 static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
18
19 static void rtw_signal_stat_timer_hdl(struct timer_list *t);
20
21 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
22 {
23         memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
24
25         spin_lock_init(&psta_recvpriv->lock);
26
27         /* for (i = 0; i<MAX_RX_NUMBLKS; i++) */
28         /*      _rtw_init_queue(&psta_recvpriv->blk_strms[i]); */
29
30         _rtw_init_queue(&psta_recvpriv->defrag_q);
31 }
32
33 sint _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
34 {
35         sint i;
36         union recv_frame *precvframe;
37         sint    res = _SUCCESS;
38
39         spin_lock_init(&precvpriv->lock);
40
41         _rtw_init_queue(&precvpriv->free_recv_queue);
42         _rtw_init_queue(&precvpriv->recv_pending_queue);
43         _rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
44
45         precvpriv->adapter = padapter;
46
47         precvpriv->free_recvframe_cnt = NR_RECVFRAME;
48
49         precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
50
51         if (!precvpriv->pallocated_frame_buf) {
52                 res = _FAIL;
53                 goto exit;
54         }
55
56         precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
57         /* precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - */
58         /*                                              ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); */
59
60         precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
61
62
63         for (i = 0; i < NR_RECVFRAME; i++) {
64                 INIT_LIST_HEAD(&(precvframe->u.list));
65
66                 list_add_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
67
68                 rtw_os_recv_resource_alloc(padapter, precvframe);
69
70                 precvframe->u.hdr.len = 0;
71
72                 precvframe->u.hdr.adapter = padapter;
73                 precvframe++;
74
75         }
76
77         res = rtw_hal_init_recv_priv(padapter);
78
79         timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl,
80                     0);
81
82         precvpriv->signal_stat_sampling_interval = 2000; /* ms */
83
84         rtw_set_signal_stat_timer(precvpriv);
85
86 exit:
87         return res;
88 }
89
90 void _rtw_free_recv_priv(struct recv_priv *precvpriv)
91 {
92         struct adapter  *padapter = precvpriv->adapter;
93
94         rtw_free_uc_swdec_pending_queue(padapter);
95
96         rtw_os_recv_resource_free(precvpriv);
97
98         if (precvpriv->pallocated_frame_buf)
99                 vfree(precvpriv->pallocated_frame_buf);
100
101         rtw_hal_free_recv_priv(padapter);
102 }
103
104 union recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
105 {
106
107         union recv_frame  *precvframe;
108         struct list_head        *plist, *phead;
109         struct adapter *padapter;
110         struct recv_priv *precvpriv;
111
112         if (list_empty(&pfree_recv_queue->queue))
113                 precvframe = NULL;
114         else {
115                 phead = get_list_head(pfree_recv_queue);
116
117                 plist = get_next(phead);
118
119                 precvframe = (union recv_frame *)plist;
120
121                 list_del_init(&precvframe->u.hdr.list);
122                 padapter = precvframe->u.hdr.adapter;
123                 if (padapter) {
124                         precvpriv = &padapter->recvpriv;
125                         if (pfree_recv_queue == &precvpriv->free_recv_queue)
126                                 precvpriv->free_recvframe_cnt--;
127                 }
128         }
129         return precvframe;
130 }
131
132 union recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
133 {
134         union recv_frame  *precvframe;
135
136         spin_lock_bh(&pfree_recv_queue->lock);
137
138         precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
139
140         spin_unlock_bh(&pfree_recv_queue->lock);
141
142         return precvframe;
143 }
144
145 int rtw_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue)
146 {
147         struct adapter *padapter = precvframe->u.hdr.adapter;
148         struct recv_priv *precvpriv = &padapter->recvpriv;
149
150         rtw_os_free_recvframe(precvframe);
151
152
153         spin_lock_bh(&pfree_recv_queue->lock);
154
155         list_del_init(&(precvframe->u.hdr.list));
156
157         precvframe->u.hdr.len = 0;
158
159         list_add_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
160
161         if (padapter) {
162                 if (pfree_recv_queue == &precvpriv->free_recv_queue)
163                                 precvpriv->free_recvframe_cnt++;
164         }
165         spin_unlock_bh(&pfree_recv_queue->lock);
166         return _SUCCESS;
167 }
168
169
170
171
172 sint _rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue)
173 {
174
175         struct adapter *padapter = precvframe->u.hdr.adapter;
176         struct recv_priv *precvpriv = &padapter->recvpriv;
177
178         /* INIT_LIST_HEAD(&(precvframe->u.hdr.list)); */
179         list_del_init(&(precvframe->u.hdr.list));
180
181
182         list_add_tail(&(precvframe->u.hdr.list), get_list_head(queue));
183
184         if (padapter)
185                 if (queue == &precvpriv->free_recv_queue)
186                         precvpriv->free_recvframe_cnt++;
187
188         return _SUCCESS;
189 }
190
191 sint rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue)
192 {
193         sint ret;
194
195         /* _spinlock(&pfree_recv_queue->lock); */
196         spin_lock_bh(&queue->lock);
197         ret = _rtw_enqueue_recvframe(precvframe, queue);
198         /* spin_unlock(&pfree_recv_queue->lock); */
199         spin_unlock_bh(&queue->lock);
200
201         return ret;
202 }
203
204 /*
205 sint    rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue)
206 {
207         return rtw_free_recvframe(precvframe, queue);
208 }
209 */
210
211
212
213
214 /*
215 caller : defrag ; recvframe_chk_defrag in recv_thread  (passive)
216 pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
217
218 using spinlock to protect
219
220 */
221
222 void rtw_free_recvframe_queue(struct __queue *pframequeue,  struct __queue *pfree_recv_queue)
223 {
224         union   recv_frame      *precvframe;
225         struct list_head        *plist, *phead;
226
227         spin_lock(&pframequeue->lock);
228
229         phead = get_list_head(pframequeue);
230         plist = get_next(phead);
231
232         while (phead != plist) {
233                 precvframe = (union recv_frame *)plist;
234
235                 plist = get_next(plist);
236
237                 rtw_free_recvframe(precvframe, pfree_recv_queue);
238         }
239
240         spin_unlock(&pframequeue->lock);
241 }
242
243 u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter)
244 {
245         u32 cnt = 0;
246         union recv_frame *pending_frame;
247         while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
248                 rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
249                 cnt++;
250         }
251
252         if (cnt)
253                 DBG_871X(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt);
254
255         return cnt;
256 }
257
258
259 sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue)
260 {
261         spin_lock_bh(&queue->lock);
262
263         list_del_init(&precvbuf->list);
264         list_add(&precvbuf->list, get_list_head(queue));
265
266         spin_unlock_bh(&queue->lock);
267
268         return _SUCCESS;
269 }
270
271 sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue)
272 {
273         spin_lock_bh(&queue->lock);
274
275         list_del_init(&precvbuf->list);
276
277         list_add_tail(&precvbuf->list, get_list_head(queue));
278         spin_unlock_bh(&queue->lock);
279         return _SUCCESS;
280
281 }
282
283 struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue)
284 {
285         struct recv_buf *precvbuf;
286         struct list_head        *plist, *phead;
287
288         spin_lock_bh(&queue->lock);
289
290         if (list_empty(&queue->queue))
291                 precvbuf = NULL;
292         else {
293                 phead = get_list_head(queue);
294
295                 plist = get_next(phead);
296
297                 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
298
299                 list_del_init(&precvbuf->list);
300
301         }
302
303         spin_unlock_bh(&queue->lock);
304
305         return precvbuf;
306
307 }
308
309 sint recvframe_chkmic(struct adapter *adapter,  union recv_frame *precvframe);
310 sint recvframe_chkmic(struct adapter *adapter,  union recv_frame *precvframe)
311 {
312
313         sint    i, res = _SUCCESS;
314         u32 datalen;
315         u8 miccode[8];
316         u8 bmic_err = false, brpt_micerror = true;
317         u8 *pframe, *payload, *pframemic;
318         u8 *mickey;
319         /* u8 *iv, rxdata_key_idx = 0; */
320         struct  sta_info        *stainfo;
321         struct  rx_pkt_attrib   *prxattrib = &precvframe->u.hdr.attrib;
322         struct  security_priv *psecuritypriv = &adapter->securitypriv;
323
324         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
325         struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
326
327         stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
328
329         if (prxattrib->encrypt == _TKIP_) {
330                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic:prxattrib->encrypt == _TKIP_\n"));
331                 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",
332                         prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2], prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5]));
333
334                 /* calculate mic code */
335                 if (stainfo) {
336                         if (IS_MCAST(prxattrib->ra)) {
337                                 /* mickey =&psecuritypriv->dot118021XGrprxmickey.skey[0]; */
338                                 /* iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; */
339                                 /* rxdata_key_idx =(((iv[3])>>6)&0x3) ; */
340                                 mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
341
342                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic: bcmc key\n"));
343                                 /* DBG_871X("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d), pmlmeinfo->key_index(%d) , recv key_id(%d)\n", */
344                                 /*                                                              psecuritypriv->dot118021XGrpKeyid, pmlmeinfo->key_index, rxdata_key_idx); */
345
346                                 if (psecuritypriv->binstallGrpkey == false) {
347                                         res = _FAIL;
348                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"));
349                                         DBG_871X("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
350                                         goto exit;
351                                 }
352                         } else {
353                                 mickey = &stainfo->dot11tkiprxmickey.skey[0];
354                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic: unicast key\n"));
355                         }
356
357                         datalen = precvframe->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len-prxattrib->icv_len-8;/* icv_len included the mic code */
358                         pframe = precvframe->u.hdr.rx_data;
359                         payload = pframe+prxattrib->hdrlen+prxattrib->iv_len;
360
361                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n prxattrib->iv_len =%d prxattrib->icv_len =%d\n", prxattrib->iv_len, prxattrib->icv_len));
362
363
364                         rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0], (unsigned char)prxattrib->priority); /* care the length of the data */
365
366                         pframemic = payload+datalen;
367
368                         bmic_err = false;
369
370                         for (i = 0; i < 8; i++) {
371                                 if (miccode[i] != *(pframemic+i)) {
372                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ", i, miccode[i], i, *(pframemic+i)));
373                                         bmic_err = true;
374                                 }
375                         }
376
377
378                         if (bmic_err == true) {
379
380                                 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",
381                                         *(pframemic-8), *(pframemic-7), *(pframemic-6), *(pframemic-5), *(pframemic-4), *(pframemic-3), *(pframemic-2), *(pframemic-1)));
382                                 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",
383                                         *(pframemic-16), *(pframemic-15), *(pframemic-14), *(pframemic-13), *(pframemic-12), *(pframemic-11), *(pframemic-10), *(pframemic-9)));
384
385                                 {
386                                         uint i;
387                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet (len =%d) ======\n", precvframe->u.hdr.len));
388                                         for (i = 0; i < precvframe->u.hdr.len; i = i+8) {
389                                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x",
390                                                         *(precvframe->u.hdr.rx_data+i), *(precvframe->u.hdr.rx_data+i+1),
391                                                         *(precvframe->u.hdr.rx_data+i+2), *(precvframe->u.hdr.rx_data+i+3),
392                                                         *(precvframe->u.hdr.rx_data+i+4), *(precvframe->u.hdr.rx_data+i+5),
393                                                         *(precvframe->u.hdr.rx_data+i+6), *(precvframe->u.hdr.rx_data+i+7)));
394                                         }
395                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet end [len =%d]======\n", precvframe->u.hdr.len));
396                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n hrdlen =%d,\n", prxattrib->hdrlen));
397                                 }
398
399                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ra = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey =%d ",
400                                         prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2],
401                                         prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5], psecuritypriv->binstallGrpkey));
402
403                                 /*  double check key_index for some timing issue , */
404                                 /*  cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
405                                 if ((IS_MCAST(prxattrib->ra) == true)  && (prxattrib->key_index != pmlmeinfo->key_index))
406                                         brpt_micerror = false;
407
408                                 if ((prxattrib->bdecrypted == true) && (brpt_micerror == true)) {
409                                         rtw_handle_tkip_mic_err(adapter, (u8)IS_MCAST(prxattrib->ra));
410                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted));
411                                         DBG_871X(" mic error :prxattrib->bdecrypted =%d\n", prxattrib->bdecrypted);
412                                 } else {
413                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted));
414                                         DBG_871X(" mic error :prxattrib->bdecrypted =%d\n", prxattrib->bdecrypted);
415                                 }
416
417                                 res = _FAIL;
418
419                         } else {
420                                 /* mic checked ok */
421                                 if ((psecuritypriv->bcheck_grpkey == false) && (IS_MCAST(prxattrib->ra) == true)) {
422                                         psecuritypriv->bcheck_grpkey = true;
423                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("psecuritypriv->bcheck_grpkey =true"));
424                                 }
425                         }
426
427                 } else
428                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic: rtw_get_stainfo == NULL!!!\n"));
429
430                 recvframe_pull_tail(precvframe, 8);
431
432         }
433
434 exit:
435         return res;
436
437 }
438
439 /* decrypt and set the ivlen, icvlen of the recv_frame */
440 union recv_frame *decryptor(struct adapter *padapter, union recv_frame *precv_frame);
441 union recv_frame *decryptor(struct adapter *padapter, union recv_frame *precv_frame)
442 {
443
444         struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
445         struct security_priv *psecuritypriv = &padapter->securitypriv;
446         union recv_frame *return_packet = precv_frame;
447         u32  res = _SUCCESS;
448
449         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt);
450
451         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n", prxattrib->bdecrypted, prxattrib->encrypt));
452
453         if (prxattrib->encrypt > 0) {
454                 u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen;
455                 prxattrib->key_index = (((iv[3])>>6)&0x3);
456
457                 if (prxattrib->key_index > WEP_KEYS) {
458                         DBG_871X("prxattrib->key_index(%d) > WEP_KEYS\n", prxattrib->key_index);
459
460                         switch (prxattrib->encrypt) {
461                         case _WEP40_:
462                         case _WEP104_:
463                                 prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
464                                 break;
465                         case _TKIP_:
466                         case _AES_:
467                         default:
468                                 prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
469                                 break;
470                         }
471                 }
472         }
473
474         if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt == true))) {
475                 psecuritypriv->hw_decrypted = false;
476
477                 #ifdef DBG_RX_DECRYPTOR
478                 DBG_871X("[%s] %d:prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n",
479                         __func__,
480                         __LINE__,
481                         prxattrib->bdecrypted,
482                         prxattrib->encrypt,
483                         psecuritypriv->hw_decrypted);
484                 #endif
485
486                 switch (prxattrib->encrypt) {
487                 case _WEP40_:
488                 case _WEP104_:
489                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep);
490                         rtw_wep_decrypt(padapter, (u8 *)precv_frame);
491                         break;
492                 case _TKIP_:
493                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip);
494                         res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
495                         break;
496                 case _AES_:
497                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes);
498                         res = rtw_aes_decrypt(padapter, (u8 *)precv_frame);
499                         break;
500                 default:
501                                 break;
502                 }
503         } else if (prxattrib->bdecrypted == 1
504                 && prxattrib->encrypt > 0
505                 && (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)
506                 ) {
507                 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw);
508
509                 psecuritypriv->hw_decrypted = true;
510                 #ifdef DBG_RX_DECRYPTOR
511                 DBG_871X("[%s] %d:prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n",
512                         __func__,
513                         __LINE__,
514                         prxattrib->bdecrypted,
515                         prxattrib->encrypt,
516                         psecuritypriv->hw_decrypted);
517
518                 #endif
519         } else {
520                 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown);
521                 #ifdef DBG_RX_DECRYPTOR
522                 DBG_871X("[%s] %d:prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n",
523                         __func__,
524                         __LINE__,
525                         prxattrib->bdecrypted,
526                         prxattrib->encrypt,
527                         psecuritypriv->hw_decrypted);
528                 #endif
529         }
530
531         if (res == _FAIL) {
532                 rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
533                 return_packet = NULL;
534         } else
535                 prxattrib->bdecrypted = true;
536
537         return return_packet;
538 }
539
540 /* set the security information in the recv_frame */
541 union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame);
542 union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame)
543 {
544         u8 *psta_addr = NULL;
545         u8 *ptr;
546         uint  auth_alg;
547         struct recv_frame_hdr *pfhdr;
548         struct sta_info *psta;
549         struct sta_priv *pstapriv;
550         union recv_frame *prtnframe;
551         u16 ether_type = 0;
552         u16  eapol_type = 0x888e;/* for Funia BD's WPA issue */
553         struct rx_pkt_attrib *pattrib;
554
555         pstapriv = &adapter->stapriv;
556
557         auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
558
559         ptr = get_recvframe_data(precv_frame);
560         pfhdr = &precv_frame->u.hdr;
561         pattrib = &pfhdr->attrib;
562         psta_addr = pattrib->ta;
563
564         prtnframe = NULL;
565
566         psta = rtw_get_stainfo(pstapriv, psta_addr);
567
568         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm =%d\n", adapter->securitypriv.dot11AuthAlgrthm));
569
570         if (auth_alg == 2) {
571                 if ((psta) && (psta->ieee8021x_blocked)) {
572                         __be16 be_tmp;
573
574                         /* blocked */
575                         /* only accept EAPOL frame */
576                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked == 1\n"));
577
578                         prtnframe = precv_frame;
579
580                         /* get ether_type */
581                         ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
582                         memcpy(&be_tmp, ptr, 2);
583                         ether_type = ntohs(be_tmp);
584
585                         if (ether_type == eapol_type)
586                                 prtnframe = precv_frame;
587                         else {
588                                 /* free this frame */
589                                 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
590                                 prtnframe = NULL;
591                         }
592                 } else {
593                         /* allowed */
594                         /* check decryption status, and decrypt the frame if needed */
595                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked == 0\n"));
596                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:precv_frame->hdr.attrib.privacy =%x\n", precv_frame->u.hdr.attrib.privacy));
597
598                         if (pattrib->bdecrypted == 0)
599                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:prxstat->decrypted =%x\n", pattrib->bdecrypted));
600
601                         prtnframe = precv_frame;
602                         /* check is the EAPOL frame or not (Rekey) */
603                         /* if (ether_type == eapol_type) { */
604                         /*      RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("########portctrl:ether_type == 0x888e\n")); */
605                                 /* check Rekey */
606
607                         /*      prtnframe =precv_frame; */
608                         /*  */
609                         /* else { */
610                         /*      RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:ether_type = 0x%04x\n", ether_type)); */
611                         /*  */
612                 }
613         } else
614                 prtnframe = precv_frame;
615
616         return prtnframe;
617 }
618
619 sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache);
620 sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache)
621 {
622         sint tid = precv_frame->u.hdr.attrib.priority;
623
624         u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
625                 (precv_frame->u.hdr.attrib.frag_num & 0xf);
626
627         if (tid > 15) {
628                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n", seq_ctrl, tid));
629
630                 return _FAIL;
631         }
632
633         if (1) { /* if (bretry) */
634                 if (seq_ctrl == prxcache->tid_rxseq[tid]) {
635                         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]));
636
637                         return _FAIL;
638                 }
639         }
640
641         prxcache->tid_rxseq[tid] = seq_ctrl;
642
643         return _SUCCESS;
644
645 }
646
647 void process_pwrbit_data(struct adapter *padapter, union recv_frame *precv_frame);
648 void process_pwrbit_data(struct adapter *padapter, union recv_frame *precv_frame)
649 {
650         unsigned char pwrbit;
651         u8 *ptr = precv_frame->u.hdr.rx_data;
652         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
653         struct sta_priv *pstapriv = &padapter->stapriv;
654         struct sta_info *psta = NULL;
655
656         psta = rtw_get_stainfo(pstapriv, pattrib->src);
657
658         pwrbit = GetPwrMgt(ptr);
659
660         if (psta) {
661                 if (pwrbit) {
662                         if (!(psta->state & WIFI_SLEEP_STATE)) {
663                                 /* psta->state |= WIFI_SLEEP_STATE; */
664                                 /* pstapriv->sta_dz_bitmap |= BIT(psta->aid); */
665
666                                 stop_sta_xmit(padapter, psta);
667
668                                 /* DBG_871X("to sleep, sta_dz_bitmap =%x\n", pstapriv->sta_dz_bitmap); */
669                         }
670                 } else {
671                         if (psta->state & WIFI_SLEEP_STATE) {
672                                 /* psta->state ^= WIFI_SLEEP_STATE; */
673                                 /* pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); */
674
675                                 wakeup_sta_to_xmit(padapter, psta);
676
677                                 /* DBG_871X("to wakeup, sta_dz_bitmap =%x\n", pstapriv->sta_dz_bitmap); */
678                         }
679                 }
680
681         }
682 }
683
684 void process_wmmps_data(struct adapter *padapter, union recv_frame *precv_frame);
685 void process_wmmps_data(struct adapter *padapter, union recv_frame *precv_frame)
686 {
687         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
688         struct sta_priv *pstapriv = &padapter->stapriv;
689         struct sta_info *psta = NULL;
690
691         psta = rtw_get_stainfo(pstapriv, pattrib->src);
692
693         if (!psta)
694                 return;
695
696         if (!psta->qos_option)
697                 return;
698
699         if (!(psta->qos_info&0xf))
700                 return;
701
702         if (psta->state&WIFI_SLEEP_STATE) {
703                 u8 wmmps_ac = 0;
704
705                 switch (pattrib->priority) {
706                 case 1:
707                 case 2:
708                         wmmps_ac = psta->uapsd_bk&BIT(1);
709                         break;
710                 case 4:
711                 case 5:
712                         wmmps_ac = psta->uapsd_vi&BIT(1);
713                         break;
714                 case 6:
715                 case 7:
716                         wmmps_ac = psta->uapsd_vo&BIT(1);
717                         break;
718                 case 0:
719                 case 3:
720                 default:
721                         wmmps_ac = psta->uapsd_be&BIT(1);
722                         break;
723                 }
724
725                 if (wmmps_ac) {
726                         if (psta->sleepq_ac_len > 0)
727                                 /* process received triggered frame */
728                                 xmit_delivery_enabled_frames(padapter, psta);
729                         else
730                                 /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */
731                                 issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0);
732                 }
733         }
734 }
735
736 void count_rx_stats(struct adapter *padapter, union recv_frame *prframe, struct sta_info *sta);
737 void count_rx_stats(struct adapter *padapter, union recv_frame *prframe, struct sta_info *sta)
738 {
739         int     sz;
740         struct sta_info         *psta = NULL;
741         struct stainfo_stats    *pstats = NULL;
742         struct rx_pkt_attrib    *pattrib = &prframe->u.hdr.attrib;
743         struct recv_priv        *precvpriv = &padapter->recvpriv;
744
745         sz = get_recvframe_len(prframe);
746         precvpriv->rx_bytes += sz;
747
748         padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
749
750         if ((!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))) {
751                 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
752         }
753
754         if (sta)
755                 psta = sta;
756         else
757                 psta = prframe->u.hdr.psta;
758
759         if (psta) {
760                 pstats = &psta->sta_stats;
761
762                 pstats->rx_data_pkts++;
763                 pstats->rx_bytes += sz;
764         }
765
766         traffic_check_for_leave_lps(padapter, false, 0);
767 }
768
769 sint sta2sta_data_frame(
770         struct adapter *adapter,
771         union recv_frame *precv_frame,
772         struct sta_info **psta
773 );
774 sint sta2sta_data_frame(
775         struct adapter *adapter,
776         union recv_frame *precv_frame,
777         struct sta_info **psta
778 )
779 {
780         u8 *ptr = precv_frame->u.hdr.rx_data;
781         sint ret = _SUCCESS;
782         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
783         struct  sta_priv        *pstapriv = &adapter->stapriv;
784         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
785         u8 *mybssid  = get_bssid(pmlmepriv);
786         u8 *myhwaddr = myid(&adapter->eeprompriv);
787         u8 *sta_addr = NULL;
788         sint bmcast = IS_MCAST(pattrib->dst);
789
790         /* DBG_871X("[%s] %d, seqnum:%d\n", __func__, __LINE__, pattrib->seq_num); */
791
792         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
793                 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
794
795                 /*  filter packets that SA is myself or multicast or broadcast */
796                 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
797                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA ==myself\n"));
798                         ret = _FAIL;
799                         goto exit;
800                 }
801
802                 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN))  && (!bmcast)) {
803                         ret = _FAIL;
804                         goto exit;
805                 }
806
807                 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
808                    !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
809                    (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
810                         ret = _FAIL;
811                         goto exit;
812                 }
813
814                 sta_addr = pattrib->src;
815
816         } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
817                 /*  For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
818                 if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
819                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("bssid != TA under STATION_MODE; drop pkt\n"));
820                         ret = _FAIL;
821                         goto exit;
822                 }
823
824                 sta_addr = pattrib->bssid;
825         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
826                 if (bmcast) {
827                         /*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
828                         if (!IS_MCAST(pattrib->bssid)) {
829                                         ret = _FAIL;
830                                         goto exit;
831                         }
832                 } else { /*  not mc-frame */
833                         /*  For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
834                         if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
835                                 ret = _FAIL;
836                                 goto exit;
837                         }
838
839                         sta_addr = pattrib->src;
840                 }
841
842         } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
843                 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
844                 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
845                 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
846                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
847                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
848
849                 sta_addr = mybssid;
850         } else
851                 ret  = _FAIL;
852
853
854
855         if (bmcast)
856                 *psta = rtw_get_bcmc_stainfo(adapter);
857         else
858                 *psta = rtw_get_stainfo(pstapriv, sta_addr); /*  get ap_info */
859
860         if (!*psta) {
861                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under sta2sta_data_frame ; drop pkt\n"));
862                 ret = _FAIL;
863                 goto exit;
864         }
865
866 exit:
867         return ret;
868 }
869
870 sint ap2sta_data_frame(
871         struct adapter *adapter,
872         union recv_frame *precv_frame,
873         struct sta_info **psta);
874 sint ap2sta_data_frame(
875         struct adapter *adapter,
876         union recv_frame *precv_frame,
877         struct sta_info **psta)
878 {
879         u8 *ptr = precv_frame->u.hdr.rx_data;
880         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
881         sint ret = _SUCCESS;
882         struct  sta_priv        *pstapriv = &adapter->stapriv;
883         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
884         u8 *mybssid  = get_bssid(pmlmepriv);
885         u8 *myhwaddr = myid(&adapter->eeprompriv);
886         sint bmcast = IS_MCAST(pattrib->dst);
887
888         if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
889                 && (check_fwstate(pmlmepriv, _FW_LINKED) == true
890                         || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
891                 ) {
892
893                 /*  filter packets that SA is myself or multicast or broadcast */
894                 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
895                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA ==myself\n"));
896                         #ifdef DBG_RX_DROP_FRAME
897                         DBG_871X("DBG_RX_DROP_FRAME %s SA ="MAC_FMT", myhwaddr ="MAC_FMT"\n",
898                                 __func__, MAC_ARG(pattrib->src), MAC_ARG(myhwaddr));
899                         #endif
900                         ret = _FAIL;
901                         goto exit;
902                 }
903
904                 /*  da should be for me */
905                 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
906                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
907                                 (" ap2sta_data_frame:  compare DA fail; DA ="MAC_FMT"\n", MAC_ARG(pattrib->dst)));
908                         #ifdef DBG_RX_DROP_FRAME
909                         DBG_871X("DBG_RX_DROP_FRAME %s DA ="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst));
910                         #endif
911                         ret = _FAIL;
912                         goto exit;
913                 }
914
915
916                 /*  check BSSID */
917                 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
918                      !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
919                      (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
920                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
921                                 (" ap2sta_data_frame:  compare BSSID fail ; BSSID ="MAC_FMT"\n", MAC_ARG(pattrib->bssid)));
922                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("mybssid ="MAC_FMT"\n", MAC_ARG(mybssid)));
923                         #ifdef DBG_RX_DROP_FRAME
924                         DBG_871X("DBG_RX_DROP_FRAME %s BSSID ="MAC_FMT", mybssid ="MAC_FMT"\n",
925                                 __func__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
926                         DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct adapter->adapter_type);
927                         #endif
928
929                         if (!bmcast) {
930                                 DBG_871X("issue_deauth to the nonassociated ap =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
931                                 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
932                         }
933
934                         ret = _FAIL;
935                         goto exit;
936                 }
937
938                 if (bmcast)
939                         *psta = rtw_get_bcmc_stainfo(adapter);
940                 else
941                         *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get ap_info */
942
943                 if (!*psta) {
944                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ap2sta: can't get psta under STATION_MODE ; drop pkt\n"));
945                         #ifdef DBG_RX_DROP_FRAME
946                         DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __func__);
947                         #endif
948                         ret = _FAIL;
949                         goto exit;
950                 }
951
952                 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
953                 }
954
955                 if (GetFrameSubType(ptr) & BIT(6)) {
956                         /* No data, will not indicate to upper layer, temporily count it here */
957                         count_rx_stats(adapter, precv_frame, *psta);
958                         ret = RTW_RX_HANDLED;
959                         goto exit;
960                 }
961
962         } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) &&
963                      (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
964                 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
965                 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
966                 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
967                 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
968                 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
969
970                 /*  */
971                 memcpy(pattrib->bssid,  mybssid, ETH_ALEN);
972
973
974                 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
975                 if (!*psta) {
976                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n"));
977                         #ifdef DBG_RX_DROP_FRAME
978                         DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __func__);
979                         #endif
980                         ret = _FAIL;
981                         goto exit;
982                 }
983
984
985         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
986                 /* Special case */
987                 ret = RTW_RX_HANDLED;
988                 goto exit;
989         } else {
990                 if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
991                         *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
992                         if (!*psta) {
993
994                                 /* for AP multicast issue , modify by yiwei */
995                                 static unsigned long send_issue_deauth_time;
996
997                                 /* DBG_871X("After send deauth , %u ms has elapsed.\n", jiffies_to_msecs(jiffies - send_issue_deauth_time)); */
998
999                                 if (jiffies_to_msecs(jiffies - send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) {
1000                                         send_issue_deauth_time = jiffies;
1001
1002                                         DBG_871X("issue_deauth to the ap =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1003
1004                                         issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1005                                 }
1006                         }
1007                 }
1008
1009                 ret = _FAIL;
1010                 #ifdef DBG_RX_DROP_FRAME
1011                 DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __func__, get_fwstate(pmlmepriv));
1012                 #endif
1013         }
1014
1015 exit:
1016         return ret;
1017 }
1018
1019 sint sta2ap_data_frame(
1020         struct adapter *adapter,
1021         union recv_frame *precv_frame,
1022         struct sta_info **psta);
1023 sint sta2ap_data_frame(
1024         struct adapter *adapter,
1025         union recv_frame *precv_frame,
1026         struct sta_info **psta)
1027 {
1028         u8 *ptr = precv_frame->u.hdr.rx_data;
1029         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1030         struct  sta_priv        *pstapriv = &adapter->stapriv;
1031         struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
1032         unsigned char *mybssid  = get_bssid(pmlmepriv);
1033         sint ret = _SUCCESS;
1034
1035         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1036                 /* For AP mode, RA =BSSID, TX =STA(SRC_ADDR), A3 =DST_ADDR */
1037                 if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1038                         ret = _FAIL;
1039                         goto exit;
1040                 }
1041
1042                 *psta = rtw_get_stainfo(pstapriv, pattrib->src);
1043                 if (!*psta) {
1044                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under AP_MODE; drop pkt\n"));
1045                         DBG_871X("issue_deauth to sta =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1046
1047                         issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1048
1049                         ret = RTW_RX_HANDLED;
1050                         goto exit;
1051                 }
1052
1053                 process_pwrbit_data(adapter, precv_frame);
1054
1055                 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1056                         process_wmmps_data(adapter, precv_frame);
1057                 }
1058
1059                 if (GetFrameSubType(ptr) & BIT(6)) {
1060                         /* No data, will not indicate to upper layer, temporily count it here */
1061                         count_rx_stats(adapter, precv_frame, *psta);
1062                         ret = RTW_RX_HANDLED;
1063                         goto exit;
1064                 }
1065         } else {
1066                 u8 *myhwaddr = myid(&adapter->eeprompriv);
1067                 if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1068                         ret = RTW_RX_HANDLED;
1069                         goto exit;
1070                 }
1071                 DBG_871X("issue_deauth to sta =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1072                 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1073                 ret = RTW_RX_HANDLED;
1074                 goto exit;
1075         }
1076
1077 exit:
1078         return ret;
1079 }
1080
1081 sint validate_recv_ctrl_frame(struct adapter *padapter, union recv_frame *precv_frame);
1082 sint validate_recv_ctrl_frame(struct adapter *padapter, union recv_frame *precv_frame)
1083 {
1084         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1085         struct sta_priv *pstapriv = &padapter->stapriv;
1086         u8 *pframe = precv_frame->u.hdr.rx_data;
1087         struct sta_info *psta = NULL;
1088         /* uint len = precv_frame->u.hdr.len; */
1089
1090         /* DBG_871X("+validate_recv_ctrl_frame\n"); */
1091
1092         if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1093                 return _FAIL;
1094
1095         /* receive the frames that ra(a1) is my address */
1096         if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN))
1097                 return _FAIL;
1098
1099         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1100         if (!psta)
1101                 return _FAIL;
1102
1103         /* for rx pkt statistics */
1104         psta->sta_stats.rx_ctrl_pkts++;
1105
1106         /* only handle ps-poll */
1107         if (GetFrameSubType(pframe) == WIFI_PSPOLL) {
1108                 u16 aid;
1109                 u8 wmmps_ac = 0;
1110
1111                 aid = GetAid(pframe);
1112                 if (psta->aid != aid)
1113                         return _FAIL;
1114
1115                 switch (pattrib->priority) {
1116                 case 1:
1117                 case 2:
1118                         wmmps_ac = psta->uapsd_bk&BIT(0);
1119                         break;
1120                 case 4:
1121                 case 5:
1122                         wmmps_ac = psta->uapsd_vi&BIT(0);
1123                         break;
1124                 case 6:
1125                 case 7:
1126                         wmmps_ac = psta->uapsd_vo&BIT(0);
1127                         break;
1128                 case 0:
1129                 case 3:
1130                 default:
1131                         wmmps_ac = psta->uapsd_be&BIT(0);
1132                         break;
1133                 }
1134
1135                 if (wmmps_ac)
1136                         return _FAIL;
1137
1138                 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1139                         DBG_871X("%s alive check-rx ps-poll\n", __func__);
1140                         psta->expire_to = pstapriv->expire_to;
1141                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1142                 }
1143
1144                 if ((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) {
1145                         struct list_head        *xmitframe_plist, *xmitframe_phead;
1146                         struct xmit_frame *pxmitframe = NULL;
1147                         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1148
1149                         /* spin_lock_bh(&psta->sleep_q.lock); */
1150                         spin_lock_bh(&pxmitpriv->lock);
1151
1152                         xmitframe_phead = get_list_head(&psta->sleep_q);
1153                         xmitframe_plist = get_next(xmitframe_phead);
1154
1155                         if (xmitframe_phead != xmitframe_plist) {
1156                                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1157
1158                                 xmitframe_plist = get_next(xmitframe_plist);
1159
1160                                 list_del_init(&pxmitframe->list);
1161
1162                                 psta->sleepq_len--;
1163
1164                                 if (psta->sleepq_len > 0)
1165                                         pxmitframe->attrib.mdata = 1;
1166                                 else
1167                                         pxmitframe->attrib.mdata = 0;
1168
1169                                 pxmitframe->attrib.triggered = 1;
1170
1171                                 /* DBG_871X("handling ps-poll, q_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1172
1173                                 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1174
1175                                 if (psta->sleepq_len == 0) {
1176                                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
1177
1178                                         /* DBG_871X("after handling ps-poll, tim =%x\n", pstapriv->tim_bitmap); */
1179
1180                                         /* update BCN for TIM IE */
1181                                         /* update_BCNTIM(padapter); */
1182                                         update_beacon(padapter, _TIM_IE_, NULL, true);
1183                                 }
1184
1185                                 /* spin_unlock_bh(&psta->sleep_q.lock); */
1186                                 spin_unlock_bh(&pxmitpriv->lock);
1187
1188                         } else {
1189                                 /* spin_unlock_bh(&psta->sleep_q.lock); */
1190                                 spin_unlock_bh(&pxmitpriv->lock);
1191
1192                                 /* DBG_871X("no buffered packets to xmit\n"); */
1193                                 if (pstapriv->tim_bitmap&BIT(psta->aid)) {
1194                                         if (psta->sleepq_len == 0) {
1195                                                 DBG_871X("no buffered packets to xmit\n");
1196
1197                                                 /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1198                                                 issue_nulldata_in_interrupt(padapter, psta->hwaddr);
1199                                         } else {
1200                                                 DBG_871X("error!psta->sleepq_len =%d\n", psta->sleepq_len);
1201                                                 psta->sleepq_len = 0;
1202                                         }
1203
1204                                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
1205
1206                                         /* update BCN for TIM IE */
1207                                         /* update_BCNTIM(padapter); */
1208                                         update_beacon(padapter, _TIM_IE_, NULL, true);
1209                                 }
1210                         }
1211                 }
1212         }
1213
1214         return _FAIL;
1215
1216 }
1217
1218 union recv_frame *recvframe_chk_defrag(struct adapter *padapter, union recv_frame *precv_frame);
1219 sint validate_recv_mgnt_frame(struct adapter *padapter, union recv_frame *precv_frame);
1220 sint validate_recv_mgnt_frame(struct adapter *padapter, union recv_frame *precv_frame)
1221 {
1222         /* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */
1223
1224         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n"));
1225
1226         precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1227         if (!precv_frame) {
1228                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("%s: fragment packet\n", __func__));
1229                 return _SUCCESS;
1230         }
1231
1232         {
1233                 /* for rx pkt statistics */
1234                 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data));
1235                 if (psta) {
1236                         psta->sta_stats.rx_mgnt_pkts++;
1237                         if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON)
1238                                 psta->sta_stats.rx_beacon_pkts++;
1239                         else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ)
1240                                 psta->sta_stats.rx_probereq_pkts++;
1241                         else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
1242                                 if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN))
1243                                         psta->sta_stats.rx_probersp_pkts++;
1244                                 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))
1245                                         || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
1246                                         psta->sta_stats.rx_probersp_bm_pkts++;
1247                                 else
1248                                         psta->sta_stats.rx_probersp_uo_pkts++;
1249                         }
1250                 }
1251         }
1252
1253         mgt_dispatcher(padapter, precv_frame);
1254
1255         return _SUCCESS;
1256
1257 }
1258
1259 sint validate_recv_data_frame(struct adapter *adapter, union recv_frame *precv_frame);
1260 sint validate_recv_data_frame(struct adapter *adapter, union recv_frame *precv_frame)
1261 {
1262         u8 bretry;
1263         u8 *psa, *pda, *pbssid;
1264         struct sta_info *psta = NULL;
1265         u8 *ptr = precv_frame->u.hdr.rx_data;
1266         struct rx_pkt_attrib    *pattrib = &precv_frame->u.hdr.attrib;
1267         struct security_priv *psecuritypriv = &adapter->securitypriv;
1268         sint ret = _SUCCESS;
1269
1270         bretry = GetRetry(ptr);
1271         pda = get_da(ptr);
1272         psa = get_sa(ptr);
1273         pbssid = get_hdr_bssid(ptr);
1274
1275         if (!pbssid) {
1276                 #ifdef DBG_RX_DROP_FRAME
1277                 DBG_871X("DBG_RX_DROP_FRAME %s pbssid == NULL\n", __func__);
1278                 #endif
1279                 ret = _FAIL;
1280                 goto exit;
1281         }
1282
1283         memcpy(pattrib->dst, pda, ETH_ALEN);
1284         memcpy(pattrib->src, psa, ETH_ALEN);
1285
1286         memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1287
1288         switch (pattrib->to_fr_ds) {
1289         case 0:
1290                 memcpy(pattrib->ra, pda, ETH_ALEN);
1291                 memcpy(pattrib->ta, psa, ETH_ALEN);
1292                 ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1293                 break;
1294
1295         case 1:
1296                 memcpy(pattrib->ra, pda, ETH_ALEN);
1297                 memcpy(pattrib->ta, pbssid, ETH_ALEN);
1298                 ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1299                 break;
1300
1301         case 2:
1302                 memcpy(pattrib->ra, pbssid, ETH_ALEN);
1303                 memcpy(pattrib->ta, psa, ETH_ALEN);
1304                 ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1305                 break;
1306
1307         case 3:
1308                 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1309                 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1310                 ret = _FAIL;
1311                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n"));
1312                 break;
1313
1314         default:
1315                 ret = _FAIL;
1316                 break;
1317
1318         }
1319
1320         if (ret == _FAIL) {
1321                 #ifdef DBG_RX_DROP_FRAME
1322                 DBG_871X("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __func__, pattrib->to_fr_ds, ret);
1323                 #endif
1324                 goto exit;
1325         } else if (ret == RTW_RX_HANDLED) {
1326                 goto exit;
1327         }
1328
1329
1330         if (!psta) {
1331                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" after to_fr_ds_chk; psta == NULL\n"));
1332                 #ifdef DBG_RX_DROP_FRAME
1333                 DBG_871X("DBG_RX_DROP_FRAME %s psta == NULL\n", __func__);
1334                 #endif
1335                 ret = _FAIL;
1336                 goto exit;
1337         }
1338
1339         /* psta->rssi = prxcmd->rssi; */
1340         /* psta->signal_quality = prxcmd->sq; */
1341         precv_frame->u.hdr.psta = psta;
1342
1343
1344         pattrib->amsdu = 0;
1345         pattrib->ack_policy = 0;
1346         /* parsing QC field */
1347         if (pattrib->qos == 1) {
1348                 pattrib->priority = GetPriority((ptr + 24));
1349                 pattrib->ack_policy = GetAckpolicy((ptr + 24));
1350                 pattrib->amsdu = GetAMsdu((ptr + 24));
1351                 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
1352
1353                 if (pattrib->priority != 0 && pattrib->priority != 3)
1354                         adapter->recvpriv.bIsAnyNonBEPkts = true;
1355
1356         } else {
1357                 pattrib->priority = 0;
1358                 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24;
1359         }
1360
1361
1362         if (pattrib->order)/* HT-CTRL 11n */
1363                 pattrib->hdrlen += 4;
1364
1365         precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1366
1367         /*  decache, drop duplicate recv packets */
1368         if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) {
1369                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decache : drop pkt\n"));
1370                 #ifdef DBG_RX_DROP_FRAME
1371                 DBG_871X("DBG_RX_DROP_FRAME %s recv_decache return _FAIL\n", __func__);
1372                 #endif
1373                 ret = _FAIL;
1374                 goto exit;
1375         }
1376
1377         if (pattrib->privacy) {
1378
1379                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("validate_recv_data_frame:pattrib->privacy =%x\n", pattrib->privacy));
1380                 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)));
1381
1382                 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
1383
1384                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt =%d\n", pattrib->encrypt));
1385
1386                 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1387         } else {
1388                 pattrib->encrypt = 0;
1389                 pattrib->iv_len = pattrib->icv_len = 0;
1390         }
1391
1392 exit:
1393         return ret;
1394 }
1395
1396 static sint validate_80211w_mgmt(struct adapter *adapter, union recv_frame *precv_frame)
1397 {
1398         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1399         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1400         u8 *ptr = precv_frame->u.hdr.rx_data;
1401         u8 subtype;
1402
1403         subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */
1404
1405         /* only support station mode */
1406         if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)
1407                 && adapter->securitypriv.binstallBIPkey == true) {
1408                 /* unicast management frame decrypt */
1409                 if (pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) &&
1410                         (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION)) {
1411                         u8 *mgmt_DATA;
1412                         u32 data_len = 0;
1413
1414                         pattrib->bdecrypted = 0;
1415                         pattrib->encrypt = _AES_;
1416                         pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
1417                         /* set iv and icv length */
1418                         SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1419                         memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1420                         memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1421                         /* actual management data frame body */
1422                         data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
1423                         mgmt_DATA = rtw_zmalloc(data_len);
1424                         if (!mgmt_DATA) {
1425                                 DBG_871X("%s mgmt allocate fail  !!!!!!!!!\n", __func__);
1426                                 goto validate_80211w_fail;
1427                         }
1428                         precv_frame = decryptor(adapter, precv_frame);
1429                         /* save actual management data frame body */
1430                         memcpy(mgmt_DATA, ptr+pattrib->hdrlen+pattrib->iv_len, data_len);
1431                         /* overwrite the iv field */
1432                         memcpy(ptr+pattrib->hdrlen, mgmt_DATA, data_len);
1433                         /* remove the iv and icv length */
1434                         pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len;
1435                         kfree(mgmt_DATA);
1436                         if (!precv_frame) {
1437                                 DBG_871X("%s mgmt descrypt fail  !!!!!!!!!\n", __func__);
1438                                 goto validate_80211w_fail;
1439                         }
1440                 } else if (IS_MCAST(GetAddr1Ptr(ptr)) &&
1441                         (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)) {
1442                         sint BIP_ret = _SUCCESS;
1443                         /* verify BIP MME IE of broadcast/multicast de-auth/disassoc packet */
1444                         BIP_ret = rtw_BIP_verify(adapter, (u8 *)precv_frame);
1445                         if (BIP_ret == _FAIL) {
1446                                 /* DBG_871X("802.11w BIP verify fail\n"); */
1447                                 goto validate_80211w_fail;
1448                         } else if (BIP_ret == RTW_RX_HANDLED) {
1449                                 /* DBG_871X("802.11w recv none protected packet\n"); */
1450                                 /* issue sa query request */
1451                                 issue_action_SA_Query(adapter, NULL, 0, 0);
1452                                 goto validate_80211w_fail;
1453                         }
1454                 } else { /* 802.11w protect */
1455                         if (subtype == WIFI_ACTION) {
1456                                 /* according 802.11-2012 standard, these five types are not robust types */
1457                                 if (ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC          &&
1458                                         ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT              &&
1459                                         ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM &&
1460                                         ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED  &&
1461                                         ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P) {
1462                                         DBG_871X("action frame category =%d should robust\n", ptr[WLAN_HDR_A3_LEN]);
1463                                         goto validate_80211w_fail;
1464                                 }
1465                         } else if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
1466                                 DBG_871X("802.11w recv none protected packet\n");
1467                                 /* issue sa query request */
1468                                 issue_action_SA_Query(adapter, NULL, 0, 0);
1469                                 goto validate_80211w_fail;
1470                         }
1471                 }
1472         }
1473         return _SUCCESS;
1474
1475 validate_80211w_fail:
1476         return _FAIL;
1477
1478 }
1479
1480 static inline void dump_rx_packet(u8 *ptr)
1481 {
1482         int i;
1483
1484         DBG_871X("#############################\n");
1485         for (i = 0; i < 64; i = i+8)
1486                 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i),
1487                 *(ptr+i+1), *(ptr+i+2), *(ptr+i+3), *(ptr+i+4), *(ptr+i+5), *(ptr+i+6), *(ptr+i+7));
1488         DBG_871X("#############################\n");
1489 }
1490
1491 sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame);
1492 sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame)
1493 {
1494         /* shall check frame subtype, to / from ds, da, bssid */
1495
1496         /* then call check if rx seq/frag. duplicated. */
1497
1498         u8 type;
1499         u8 subtype;
1500         sint retval = _SUCCESS;
1501         u8 bDumpRxPkt;
1502
1503         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1504
1505         u8 *ptr = precv_frame->u.hdr.rx_data;
1506         u8  ver = (unsigned char) (*ptr)&0x3;
1507
1508         /* add version chk */
1509         if (ver != 0) {
1510                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! (ver!= 0)\n"));
1511                 retval = _FAIL;
1512                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err);
1513                 goto exit;
1514         }
1515
1516         type =  GetFrameType(ptr);
1517         subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */
1518
1519         pattrib->to_fr_ds = get_tofr_ds(ptr);
1520
1521         pattrib->frag_num = GetFragNum(ptr);
1522         pattrib->seq_num = GetSequence(ptr);
1523
1524         pattrib->pw_save = GetPwrMgt(ptr);
1525         pattrib->mfrag = GetMFrag(ptr);
1526         pattrib->mdata = GetMData(ptr);
1527         pattrib->privacy = GetPrivacy(ptr);
1528         pattrib->order = GetOrder(ptr);
1529         rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
1530         if (bDumpRxPkt == 1) /* dump all rx packets */
1531                 dump_rx_packet(ptr);
1532         else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE))
1533                 dump_rx_packet(ptr);
1534         else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE))
1535                 dump_rx_packet(ptr);
1536
1537         switch (type) {
1538         case WIFI_MGT_TYPE: /* mgnt */
1539                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt);
1540                 if (validate_80211w_mgmt(adapter, precv_frame) == _FAIL) {
1541                         retval = _FAIL;
1542                         DBG_COUNTER(padapter->rx_logs.core_rx_pre_mgmt_err_80211w);
1543                         break;
1544                 }
1545
1546                 retval = validate_recv_mgnt_frame(adapter, precv_frame);
1547                 if (retval == _FAIL) {
1548                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_mgnt_frame fail\n"));
1549                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err);
1550                 }
1551                 retval = _FAIL; /*  only data frame return _SUCCESS */
1552                 break;
1553         case WIFI_CTRL_TYPE: /* ctrl */
1554                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl);
1555                 retval = validate_recv_ctrl_frame(adapter, precv_frame);
1556                 if (retval == _FAIL) {
1557                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_ctrl_frame fail\n"));
1558                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err);
1559                 }
1560                 retval = _FAIL; /*  only data frame return _SUCCESS */
1561                 break;
1562         case WIFI_DATA_TYPE: /* data */
1563                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data);
1564
1565                 pattrib->qos = (subtype & BIT(7)) ? 1:0;
1566                 retval = validate_recv_data_frame(adapter, precv_frame);
1567                 if (retval == _FAIL) {
1568                         struct recv_priv *precvpriv = &adapter->recvpriv;
1569                         /* RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail\n")); */
1570                         precvpriv->rx_drop++;
1571                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err);
1572                 } else if (retval == _SUCCESS) {
1573 #ifdef DBG_RX_DUMP_EAP
1574                         u8 bDumpRxPkt;
1575                         u16 eth_type;
1576
1577                         /*  dump eapol */
1578                         rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
1579                         /*  get ether_type */
1580                         memcpy(&eth_type, ptr + pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE, 2);
1581                         eth_type = ntohs((unsigned short) eth_type);
1582                         if ((bDumpRxPkt == 4) && (eth_type == 0x888e))
1583                                 dump_rx_packet(ptr);
1584 #endif
1585                 } else
1586                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled);
1587                 break;
1588         default:
1589                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown);
1590                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! type = 0x%x\n", type));
1591                 #ifdef DBG_RX_DROP_FRAME
1592                 DBG_871X("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type = 0x%x\n", type);
1593                 #endif
1594                 retval = _FAIL;
1595                 break;
1596         }
1597
1598 exit:
1599         return retval;
1600 }
1601
1602
1603 /* remove the wlanhdr and add the eth_hdr */
1604 sint wlanhdr_to_ethhdr(union recv_frame *precvframe);
1605 sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
1606 {
1607         sint    rmv_len;
1608         u16 eth_type, len;
1609         u8 bsnaphdr;
1610         u8 *psnap_type;
1611         struct ieee80211_snap_hdr       *psnap;
1612         __be16 be_tmp;
1613         struct adapter                  *adapter = precvframe->u.hdr.adapter;
1614         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1615         u8 *ptr = get_recvframe_data(precvframe) ; /*  point to frame_ctrl field */
1616         struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
1617
1618         if (pattrib->encrypt) {
1619                 recvframe_pull_tail(precvframe, pattrib->icv_len);
1620         }
1621
1622         psnap = (struct ieee80211_snap_hdr      *)(ptr+pattrib->hdrlen + pattrib->iv_len);
1623         psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
1624         /* convert hdr + possible LLC headers into Ethernet header */
1625         /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
1626         if ((!memcmp(psnap, rfc1042_header, SNAP_SIZE) &&
1627                 (memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2)) &&
1628                 (memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2))) ||
1629                 /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
1630                  !memcmp(psnap, bridge_tunnel_header, SNAP_SIZE)) {
1631                 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
1632                 bsnaphdr = true;
1633         } else
1634                 /* Leave Ethernet header part of hdr and full payload */
1635                 bsnaphdr = false;
1636
1637         rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr?SNAP_SIZE:0);
1638         len = precvframe->u.hdr.len - rmv_len;
1639
1640         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n ===pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n\n", pattrib->hdrlen,  pattrib->iv_len));
1641
1642         memcpy(&be_tmp, ptr+rmv_len, 2);
1643         eth_type = ntohs(be_tmp); /* pattrib->ether_type */
1644         pattrib->eth_type = eth_type;
1645
1646 #ifdef CONFIG_AUTO_AP_MODE
1647         if (0x8899 == pattrib->eth_type) {
1648                 struct sta_info *psta = precvframe->u.hdr.psta;
1649
1650                 DBG_871X("wlan rx: got eth_type = 0x%x\n", pattrib->eth_type);
1651
1652                 if (psta && psta->isrc && psta->pid > 0) {
1653                         u16 rx_pid;
1654
1655                         rx_pid = *(u16 *)(ptr+rmv_len+2);
1656
1657                         DBG_871X("wlan rx(pid = 0x%x): sta("MAC_FMT") pid = 0x%x\n",
1658                                 rx_pid, MAC_ARG(psta->hwaddr), psta->pid);
1659
1660                         if (rx_pid == psta->pid) {
1661                                 int i;
1662                                 u16 len = *(u16 *)(ptr+rmv_len+4);
1663                                 /* u16 ctrl_type = *(u16*)(ptr+rmv_len+6); */
1664
1665                                 /* DBG_871X("RC: len = 0x%x, ctrl_type = 0x%x\n", len, ctrl_type); */
1666                                 DBG_871X("RC: len = 0x%x\n", len);
1667
1668                                 for (i = 0; i < len ; i++)
1669                                         DBG_871X("0x%x\n", *(ptr+rmv_len+6+i));
1670                                         /* DBG_871X("0x%x\n", *(ptr+rmv_len+8+i)); */
1671
1672                                 DBG_871X("RC-end\n");
1673                         }
1674                 }
1675         }
1676 #endif /* CONFIG_AUTO_AP_MODE */
1677
1678         if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) {
1679                 ptr += rmv_len;
1680                 *ptr = 0x87;
1681                 *(ptr+1) = 0x12;
1682
1683                 eth_type = 0x8712;
1684                 /*  append rx status for mp test packets */
1685                 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24);
1686                 memcpy(ptr, get_rxmem(precvframe), 24);
1687                 ptr += 24;
1688         } else
1689                 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr?2:0)));
1690
1691         memcpy(ptr, pattrib->dst, ETH_ALEN);
1692         memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
1693
1694         if (!bsnaphdr) {
1695                 be_tmp = htons(len);
1696                 memcpy(ptr+12, &be_tmp, 2);
1697         }
1698
1699         return _SUCCESS;
1700 }
1701
1702 /* perform defrag */
1703 static union recv_frame *recvframe_defrag(struct adapter *adapter,
1704                                           struct __queue *defrag_q)
1705 {
1706         struct list_head         *plist, *phead;
1707         u8  wlanhdr_offset;
1708         u8 curfragnum;
1709         struct recv_frame_hdr *pfhdr, *pnfhdr;
1710         union recv_frame *prframe, *pnextrframe;
1711         struct __queue  *pfree_recv_queue;
1712
1713         curfragnum = 0;
1714         pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
1715
1716         phead = get_list_head(defrag_q);
1717         plist = get_next(phead);
1718         prframe = (union recv_frame *)plist;
1719         pfhdr = &prframe->u.hdr;
1720         list_del_init(&(prframe->u.list));
1721
1722         if (curfragnum != pfhdr->attrib.frag_num) {
1723                 /* the first fragment number must be 0 */
1724                 /* free the whole queue */
1725                 rtw_free_recvframe(prframe, pfree_recv_queue);
1726                 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1727
1728                 return NULL;
1729         }
1730
1731         curfragnum++;
1732
1733         plist = get_list_head(defrag_q);
1734
1735         plist = get_next(plist);
1736
1737         while (phead != plist) {
1738                 pnextrframe = (union recv_frame *)plist;
1739                 pnfhdr = &pnextrframe->u.hdr;
1740
1741
1742                 /* check the fragment sequence  (2nd ~n fragment frame) */
1743
1744                 if (curfragnum != pnfhdr->attrib.frag_num) {
1745                         /* the fragment number must be increasing  (after decache) */
1746                         /* release the defrag_q & prframe */
1747                         rtw_free_recvframe(prframe, pfree_recv_queue);
1748                         rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1749                         return NULL;
1750                 }
1751
1752                 curfragnum++;
1753
1754                 /* copy the 2nd~n fragment frame's payload to the first fragment */
1755                 /* get the 2nd~last fragment frame's payload */
1756
1757                 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1758
1759                 recvframe_pull(pnextrframe, wlanhdr_offset);
1760
1761                 /* append  to first fragment frame's tail (if privacy frame, pull the ICV) */
1762                 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
1763
1764                 /* memcpy */
1765                 memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
1766
1767                 recvframe_put(prframe, pnfhdr->len);
1768
1769                 pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
1770                 plist = get_next(plist);
1771
1772         }
1773
1774         /* free the defrag_q queue and return the prframe */
1775         rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1776
1777         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Performance defrag!!!!!\n"));
1778
1779         return prframe;
1780 }
1781
1782 /* check if need to defrag, if needed queue the frame to defrag_q */
1783 union recv_frame *recvframe_chk_defrag(struct adapter *padapter, union recv_frame *precv_frame)
1784 {
1785         u8 ismfrag;
1786         u8 fragnum;
1787         u8 *psta_addr;
1788         struct recv_frame_hdr *pfhdr;
1789         struct sta_info *psta;
1790         struct sta_priv *pstapriv;
1791         struct list_head *phead;
1792         union recv_frame *prtnframe = NULL;
1793         struct __queue *pfree_recv_queue, *pdefrag_q;
1794
1795         pstapriv = &padapter->stapriv;
1796
1797         pfhdr = &precv_frame->u.hdr;
1798
1799         pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1800
1801         /* need to define struct of wlan header frame ctrl */
1802         ismfrag = pfhdr->attrib.mfrag;
1803         fragnum = pfhdr->attrib.frag_num;
1804
1805         psta_addr = pfhdr->attrib.ta;
1806         psta = rtw_get_stainfo(pstapriv, psta_addr);
1807         if (!psta) {
1808                 u8 type = GetFrameType(pfhdr->rx_data);
1809                 if (type != WIFI_DATA_TYPE) {
1810                         psta = rtw_get_bcmc_stainfo(padapter);
1811                         pdefrag_q = &psta->sta_recvpriv.defrag_q;
1812                 } else
1813                         pdefrag_q = NULL;
1814         } else
1815                 pdefrag_q = &psta->sta_recvpriv.defrag_q;
1816
1817         if ((ismfrag == 0) && (fragnum == 0))
1818                 prtnframe = precv_frame;/* isn't a fragment frame */
1819
1820         if (ismfrag == 1) {
1821                 /* 0~(n-1) fragment frame */
1822                 /* enqueue to defraf_g */
1823                 if (pdefrag_q) {
1824                         if (fragnum == 0)
1825                                 /* the first fragment */
1826                                 if (!list_empty(&pdefrag_q->queue))
1827                                         /* free current defrag_q */
1828                                         rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
1829
1830
1831                         /* Then enqueue the 0~(n-1) fragment into the defrag_q */
1832
1833                         /* spin_lock(&pdefrag_q->lock); */
1834                         phead = get_list_head(pdefrag_q);
1835                         list_add_tail(&pfhdr->list, phead);
1836                         /* spin_unlock(&pdefrag_q->lock); */
1837
1838                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Enqueuq: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1839
1840                         prtnframe = NULL;
1841
1842                 } else {
1843                         /* can't find this ta's defrag_queue, so free this recv_frame */
1844                         rtw_free_recvframe(precv_frame, pfree_recv_queue);
1845                         prtnframe = NULL;
1846                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1847                 }
1848
1849         }
1850
1851         if ((ismfrag == 0) && (fragnum != 0)) {
1852                 /* the last fragment frame */
1853                 /* enqueue the last fragment */
1854                 if (pdefrag_q) {
1855                         /* spin_lock(&pdefrag_q->lock); */
1856                         phead = get_list_head(pdefrag_q);
1857                         list_add_tail(&pfhdr->list, phead);
1858                         /* spin_unlock(&pdefrag_q->lock); */
1859
1860                         /* call recvframe_defrag to defrag */
1861                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("defrag: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1862                         precv_frame = recvframe_defrag(padapter, pdefrag_q);
1863                         prtnframe = precv_frame;
1864
1865                 } else {
1866                         /* can't find this ta's defrag_queue, so free this recv_frame */
1867                         rtw_free_recvframe(precv_frame, pfree_recv_queue);
1868                         prtnframe = NULL;
1869                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1870                 }
1871
1872         }
1873
1874
1875         if ((prtnframe) && (prtnframe->u.hdr.attrib.privacy)) {
1876                 /* after defrag we must check tkip mic code */
1877                 if (recvframe_chkmic(padapter,  prtnframe) == _FAIL) {
1878                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic(padapter,  prtnframe) == _FAIL\n"));
1879                         rtw_free_recvframe(prtnframe, pfree_recv_queue);
1880                         prtnframe = NULL;
1881                 }
1882         }
1883         return prtnframe;
1884 }
1885
1886 static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe)
1887 {
1888         int     a_len, padding_len;
1889         u16 nSubframe_Length;
1890         u8 nr_subframes, i;
1891         u8 *pdata;
1892         _pkt *sub_pkt, *subframes[MAX_SUBFRAME_COUNT];
1893         struct recv_priv *precvpriv = &padapter->recvpriv;
1894         struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
1895
1896         nr_subframes = 0;
1897
1898         recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
1899
1900         if (prframe->u.hdr.attrib.iv_len > 0)
1901                 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
1902
1903         a_len = prframe->u.hdr.len;
1904
1905         pdata = prframe->u.hdr.rx_data;
1906
1907         while (a_len > ETH_HLEN) {
1908
1909                 /* Offset 12 denote 2 mac address */
1910                 nSubframe_Length = get_unaligned_be16(pdata + 12);
1911
1912                 if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
1913                         DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
1914                         break;
1915                 }
1916
1917                 sub_pkt = rtw_os_alloc_msdu_pkt(prframe, nSubframe_Length, pdata);
1918                 if (!sub_pkt) {
1919                         DBG_871X("%s(): allocate sub packet fail !!!\n", __func__);
1920                         break;
1921                 }
1922
1923                 /* move the data point to data content */
1924                 pdata += ETH_HLEN;
1925                 a_len -= ETH_HLEN;
1926
1927                 subframes[nr_subframes++] = sub_pkt;
1928
1929                 if (nr_subframes >= MAX_SUBFRAME_COUNT) {
1930                         DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n");
1931                         break;
1932                 }
1933
1934                 pdata += nSubframe_Length;
1935                 a_len -= nSubframe_Length;
1936                 if (a_len != 0) {
1937                         padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1));
1938                         if (padding_len == 4) {
1939                                 padding_len = 0;
1940                         }
1941
1942                         if (a_len < padding_len) {
1943                                 DBG_871X("ParseSubframe(): a_len < padding_len !\n");
1944                                 break;
1945                         }
1946                         pdata += padding_len;
1947                         a_len -= padding_len;
1948                 }
1949         }
1950
1951         for (i = 0; i < nr_subframes; i++) {
1952                 sub_pkt = subframes[i];
1953
1954                 /* Indicate the packets to upper layer */
1955                 if (sub_pkt) {
1956                         rtw_os_recv_indicate_pkt(padapter, sub_pkt, &prframe->u.hdr.attrib);
1957                 }
1958         }
1959
1960         prframe->u.hdr.len = 0;
1961         rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
1962
1963         return  _SUCCESS;
1964 }
1965
1966 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
1967 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
1968 {
1969         struct adapter *padapter = preorder_ctrl->padapter;
1970         struct dvobj_priv *psdpriv = padapter->dvobj;
1971         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1972         u8 wsize = preorder_ctrl->wsize_b;
1973         u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/*  4096; */
1974
1975         /*  Rx Reorder initialize condition. */
1976         if (preorder_ctrl->indicate_seq == 0xFFFF) {
1977                 preorder_ctrl->indicate_seq = seq_num;
1978                 #ifdef DBG_RX_SEQ
1979                 DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
1980                         preorder_ctrl->indicate_seq, seq_num);
1981                 #endif
1982
1983                 /* DbgPrint("check_indicate_seq, 1st->indicate_seq =%d\n", precvpriv->indicate_seq); */
1984         }
1985
1986         /* DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
1987
1988         /*  Drop out the packet which SeqNum is smaller than WinStart */
1989         if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) {
1990                 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */
1991                 /* DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
1992
1993                 #ifdef DBG_RX_DROP_FRAME
1994                 DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __func__,
1995                         preorder_ctrl->indicate_seq, seq_num);
1996                 #endif
1997
1998
1999                 return false;
2000         }
2001
2002         /*  */
2003         /*  Sliding window manipulation. Conditions includes: */
2004         /*  1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
2005         /*  2. Incoming SeqNum is larger than the WinEnd => Window shift N */
2006         /*  */
2007         if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
2008                 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2009
2010                 #ifdef DBG_RX_SEQ
2011                 DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2012                         preorder_ctrl->indicate_seq, seq_num);
2013                 #endif
2014         } else if (SN_LESS(wend, seq_num)) {
2015                 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */
2016                 /* DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2017
2018                 /*  boundary situation, when seq_num cross 0xFFF */
2019                 if (seq_num >= (wsize - 1))
2020                         preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
2021                 else
2022                         preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
2023                 pdbgpriv->dbg_rx_ampdu_window_shift_cnt++;
2024                 #ifdef DBG_RX_SEQ
2025                 DBG_871X("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2026                         preorder_ctrl->indicate_seq, seq_num);
2027                 #endif
2028         }
2029
2030         /* DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2031
2032         return true;
2033 }
2034
2035 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe);
2036 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe)
2037 {
2038         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2039         struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2040         struct list_head        *phead, *plist;
2041         union recv_frame *pnextrframe;
2042         struct rx_pkt_attrib *pnextattrib;
2043
2044         /* DbgPrint("+enqueue_reorder_recvframe()\n"); */
2045
2046         /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */
2047         /* spin_lock(&ppending_recvframe_queue->lock); */
2048
2049
2050         phead = get_list_head(ppending_recvframe_queue);
2051         plist = get_next(phead);
2052
2053         while (phead != plist) {
2054                 pnextrframe = (union recv_frame *)plist;
2055                 pnextattrib = &pnextrframe->u.hdr.attrib;
2056
2057                 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
2058                         plist = get_next(plist);
2059                 else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
2060                         /* Duplicate entry is found!! Do not insert current entry. */
2061                         /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
2062                         /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */
2063                         return false;
2064                 else
2065                         break;
2066
2067                 /* DbgPrint("enqueue_reorder_recvframe():while\n"); */
2068
2069         }
2070
2071
2072         /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */
2073         /* spin_lock(&ppending_recvframe_queue->lock); */
2074
2075         list_del_init(&(prframe->u.hdr.list));
2076
2077         list_add_tail(&(prframe->u.hdr.list), plist);
2078
2079         /* spin_unlock(&ppending_recvframe_queue->lock); */
2080         /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */
2081
2082
2083         /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
2084         return true;
2085
2086 }
2087
2088 void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq);
2089 void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq)
2090 {
2091         if (current_seq < prev_seq)
2092                 pdbgpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq);
2093         else
2094                 pdbgpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq);
2095
2096 }
2097 int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced);
2098 int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
2099 {
2100         struct list_head        *phead, *plist;
2101         union recv_frame *prframe;
2102         struct rx_pkt_attrib *pattrib;
2103         /* u8 index = 0; */
2104         int bPktInBuf = false;
2105         struct recv_priv *precvpriv = &padapter->recvpriv;
2106         struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2107         struct dvobj_priv *psdpriv = padapter->dvobj;
2108         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
2109
2110         DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder);
2111
2112         /* DbgPrint("+recv_indicatepkts_in_order\n"); */
2113
2114         /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */
2115         /* spin_lock(&ppending_recvframe_queue->lock); */
2116
2117         phead =         get_list_head(ppending_recvframe_queue);
2118         plist = get_next(phead);
2119
2120         /*  Handling some condition for forced indicate case. */
2121         if (bforced == true) {
2122                 pdbgpriv->dbg_rx_ampdu_forced_indicate_count++;
2123                 if (list_empty(phead)) {
2124                         /*  spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */
2125                         /* spin_unlock(&ppending_recvframe_queue->lock); */
2126                         return true;
2127                 }
2128
2129                 prframe = (union recv_frame *)plist;
2130                 pattrib = &prframe->u.hdr.attrib;
2131
2132                 #ifdef DBG_RX_SEQ
2133                 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2134                         preorder_ctrl->indicate_seq, pattrib->seq_num);
2135                 #endif
2136                 recv_indicatepkts_pkt_loss_cnt(pdbgpriv, preorder_ctrl->indicate_seq, pattrib->seq_num);
2137                 preorder_ctrl->indicate_seq = pattrib->seq_num;
2138
2139         }
2140
2141         /*  Prepare indication list and indication. */
2142         /*  Check if there is any packet need indicate. */
2143         while (!list_empty(phead)) {
2144
2145                 prframe = (union recv_frame *)plist;
2146                 pattrib = &prframe->u.hdr.attrib;
2147
2148                 if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
2149                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2150                                  ("recv_indicatepkts_in_order: indicate =%d seq =%d amsdu =%d\n",
2151                                   preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu));
2152
2153                         plist = get_next(plist);
2154                         list_del_init(&(prframe->u.hdr.list));
2155
2156                         if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
2157                                 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2158                                 #ifdef DBG_RX_SEQ
2159                                 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2160                                         preorder_ctrl->indicate_seq, pattrib->seq_num);
2161                                 #endif
2162                         }
2163
2164                         /* Set this as a lock to make sure that only one thread is indicating packet. */
2165                         /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */
2166
2167                         /*  Indicate packets */
2168                         /* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */
2169
2170
2171                         /* indicate this recv_frame */
2172                         /* DbgPrint("recv_indicatepkts_in_order, indicate_seq =%d, seq_num =%d\n", precvpriv->indicate_seq, pattrib->seq_num); */
2173                         if (!pattrib->amsdu) {
2174                                 /* DBG_871X("recv_indicatepkts_in_order, amsdu!= 1, indicate_seq =%d, seq_num =%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num); */
2175
2176                                 if ((padapter->bDriverStopped == false) &&
2177                                     (padapter->bSurpriseRemoved == false))
2178                                         rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */
2179
2180                         } else if (pattrib->amsdu == 1) {
2181                                 if (amsdu_to_msdu(padapter, prframe) != _SUCCESS)
2182                                         rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
2183
2184                         } else {
2185                                 /* error condition; */
2186                         }
2187
2188
2189                         /* Update local variables. */
2190                         bPktInBuf = false;
2191
2192                 } else {
2193                         bPktInBuf = true;
2194                         break;
2195                 }
2196
2197                 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
2198
2199         }
2200
2201         /* spin_unlock(&ppending_recvframe_queue->lock); */
2202         /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */
2203
2204         return bPktInBuf;
2205 }
2206
2207 int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *prframe);
2208 int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *prframe)
2209 {
2210         int retval = _SUCCESS;
2211         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2212         struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
2213         struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2214         struct dvobj_priv *psdpriv = padapter->dvobj;
2215         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
2216
2217         DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder);
2218
2219         if (!pattrib->amsdu) {
2220                 /* s1. */
2221                 wlanhdr_to_ethhdr(prframe);
2222
2223                 if (pattrib->qos != 1) {
2224                         if ((padapter->bDriverStopped == false) &&
2225                             (padapter->bSurpriseRemoved == false)) {
2226                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@  recv_indicatepkt_reorder -recv_func recv_indicatepkt\n"));
2227
2228                                 rtw_recv_indicatepkt(padapter, prframe);
2229                                 return _SUCCESS;
2230
2231                         }
2232
2233                         #ifdef DBG_RX_DROP_FRAME
2234                         DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos != 1\n", __func__);
2235                         #endif
2236
2237                         return _FAIL;
2238
2239                 }
2240
2241                 if (preorder_ctrl->enable == false) {
2242                         /* indicate this recv_frame */
2243                         preorder_ctrl->indicate_seq = pattrib->seq_num;
2244                         #ifdef DBG_RX_SEQ
2245                         DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2246                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2247                         #endif
2248
2249                         rtw_recv_indicatepkt(padapter, prframe);
2250
2251                         preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
2252                         #ifdef DBG_RX_SEQ
2253                         DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2254                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2255                         #endif
2256
2257                         return _SUCCESS;
2258                 }
2259         } else if (pattrib->amsdu == 1) { /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
2260                 if (preorder_ctrl->enable == false) {
2261                         preorder_ctrl->indicate_seq = pattrib->seq_num;
2262                         #ifdef DBG_RX_SEQ
2263                         DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2264                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2265                         #endif
2266
2267                         retval = amsdu_to_msdu(padapter, prframe);
2268
2269                         preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
2270                         #ifdef DBG_RX_SEQ
2271                         DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2272                                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2273                         #endif
2274
2275                         if (retval != _SUCCESS) {
2276                                 #ifdef DBG_RX_DROP_FRAME
2277                                 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __func__);
2278                                 #endif
2279                         }
2280
2281                         return retval;
2282                 }
2283         }
2284
2285         spin_lock_bh(&ppending_recvframe_queue->lock);
2286
2287         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2288                  ("recv_indicatepkt_reorder: indicate =%d seq =%d\n",
2289                   preorder_ctrl->indicate_seq, pattrib->seq_num));
2290
2291         /* s2. check if winstart_b(indicate_seq) needs to been updated */
2292         if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
2293                 pdbgpriv->dbg_rx_ampdu_drop_count++;
2294                 #ifdef DBG_RX_DROP_FRAME
2295                 DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __func__);
2296                 #endif
2297                 goto _err_exit;
2298         }
2299
2300
2301         /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
2302         if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) {
2303                 /* DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); */
2304                 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */
2305                 /* return _FAIL; */
2306                 #ifdef DBG_RX_DROP_FRAME
2307                 DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __func__);
2308                 #endif
2309                 goto _err_exit;
2310         }
2311
2312
2313         /* s4. */
2314         /*  Indication process. */
2315         /*  After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
2316         /*  with the SeqNum smaller than latest WinStart and buffer other packets. */
2317         /*  */
2318         /*  For Rx Reorder condition: */
2319         /*  1. All packets with SeqNum smaller than WinStart => Indicate */
2320         /*  2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
2321         /*  */
2322
2323         /* recv_indicatepkts_in_order(padapter, preorder_ctrl, true); */
2324         if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) {
2325                 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
2326                 spin_unlock_bh(&ppending_recvframe_queue->lock);
2327         } else {
2328                 spin_unlock_bh(&ppending_recvframe_queue->lock);
2329                 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
2330         }
2331
2332         return _SUCCESS;
2333
2334 _err_exit:
2335         spin_unlock_bh(&ppending_recvframe_queue->lock);
2336
2337         return _FAIL;
2338 }
2339
2340
2341 void rtw_reordering_ctrl_timeout_handler(struct timer_list *t)
2342 {
2343         struct recv_reorder_ctrl *preorder_ctrl =
2344                 from_timer(preorder_ctrl, t, reordering_ctrl_timer);
2345         struct adapter *padapter = preorder_ctrl->padapter;
2346         struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2347
2348
2349         if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2350                 return;
2351
2352         /* DBG_871X("+rtw_reordering_ctrl_timeout_handler() =>\n"); */
2353
2354         spin_lock_bh(&ppending_recvframe_queue->lock);
2355
2356         if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true)
2357                 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
2358
2359         spin_unlock_bh(&ppending_recvframe_queue->lock);
2360
2361 }
2362
2363 int process_recv_indicatepkts(struct adapter *padapter, union recv_frame *prframe);
2364 int process_recv_indicatepkts(struct adapter *padapter, union recv_frame *prframe)
2365 {
2366         int retval = _SUCCESS;
2367         /* struct recv_priv *precvpriv = &padapter->recvpriv; */
2368         /* struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; */
2369         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2370         struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2371
2372         DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate);
2373
2374         if (phtpriv->ht_option == true) { /* B/G/N Mode */
2375                 /* prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
2376
2377                 if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) { /*  including perform A-MPDU Rx Ordering Buffer Control */
2378                         #ifdef DBG_RX_DROP_FRAME
2379                         DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __func__);
2380                         #endif
2381
2382                         if ((padapter->bDriverStopped == false) &&
2383                             (padapter->bSurpriseRemoved == false)) {
2384                                 retval = _FAIL;
2385                                 return retval;
2386                         }
2387                 }
2388         } else { /* B/G mode */
2389                 retval = wlanhdr_to_ethhdr(prframe);
2390                 if (retval != _SUCCESS) {
2391                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n"));
2392                         #ifdef DBG_RX_DROP_FRAME
2393                         DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __func__);
2394                         #endif
2395                         return retval;
2396                 }
2397
2398                 if ((padapter->bDriverStopped == false) && (padapter->bSurpriseRemoved == false)) {
2399                         /* indicate this recv_frame */
2400                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n"));
2401                         rtw_recv_indicatepkt(padapter, prframe);
2402
2403
2404                 } else {
2405                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n"));
2406
2407                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
2408                         retval = _FAIL;
2409                         return retval;
2410                 }
2411
2412         }
2413
2414         return retval;
2415
2416 }
2417
2418 static int recv_func_prehandle(struct adapter *padapter, union recv_frame *rframe)
2419 {
2420         int ret = _SUCCESS;
2421         struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2422
2423         DBG_COUNTER(padapter->rx_logs.core_rx_pre);
2424
2425         /* check the frame crtl field and decache */
2426         ret = validate_recv_frame(padapter, rframe);
2427         if (ret != _SUCCESS) {
2428                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n"));
2429                 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
2430                 goto exit;
2431         }
2432
2433 exit:
2434         return ret;
2435 }
2436
2437 static int recv_func_posthandle(struct adapter *padapter, union recv_frame *prframe)
2438 {
2439         int ret = _SUCCESS;
2440         union recv_frame *orig_prframe = prframe;
2441         struct recv_priv *precvpriv = &padapter->recvpriv;
2442         struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2443
2444         DBG_COUNTER(padapter->rx_logs.core_rx_post);
2445
2446         prframe = decryptor(padapter, prframe);
2447         if (!prframe) {
2448                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decryptor: drop pkt\n"));
2449                 #ifdef DBG_RX_DROP_FRAME
2450                 DBG_871X("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __func__);
2451                 #endif
2452                 ret = _FAIL;
2453                 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err);
2454                 goto _recv_data_drop;
2455         }
2456
2457         prframe = recvframe_chk_defrag(padapter, prframe);
2458         if (!prframe)   {
2459                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chk_defrag: drop pkt\n"));
2460                 #ifdef DBG_RX_DROP_FRAME
2461                 DBG_871X("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __func__);
2462                 #endif
2463                 DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err);
2464                 goto _recv_data_drop;
2465         }
2466
2467         prframe = portctrl(padapter, prframe);
2468         if (!prframe) {
2469                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("portctrl: drop pkt\n"));
2470                 #ifdef DBG_RX_DROP_FRAME
2471                 DBG_871X("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __func__);
2472                 #endif
2473                 ret = _FAIL;
2474                 DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err);
2475                 goto _recv_data_drop;
2476         }
2477
2478         count_rx_stats(padapter, prframe, NULL);
2479
2480         ret = process_recv_indicatepkts(padapter, prframe);
2481         if (ret != _SUCCESS) {
2482                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recv_func: process_recv_indicatepkts fail!\n"));
2483                 #ifdef DBG_RX_DROP_FRAME
2484                 DBG_871X("DBG_RX_DROP_FRAME %s process_recv_indicatepkts fail!\n", __func__);
2485                 #endif
2486                 rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
2487                 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_err);
2488                 goto _recv_data_drop;
2489         }
2490
2491 _recv_data_drop:
2492         precvpriv->rx_drop++;
2493         return ret;
2494 }
2495
2496
2497 int recv_func(struct adapter *padapter, union recv_frame *rframe);
2498 int recv_func(struct adapter *padapter, union recv_frame *rframe)
2499 {
2500         int ret;
2501         struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
2502         struct recv_priv *recvpriv = &padapter->recvpriv;
2503         struct security_priv *psecuritypriv = &padapter->securitypriv;
2504         struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2505
2506         /* check if need to handle uc_swdec_pending_queue*/
2507         if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) {
2508                 union recv_frame *pending_frame;
2509                 int cnt = 0;
2510
2511                 while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) {
2512                         cnt++;
2513                         DBG_COUNTER(padapter->rx_logs.core_rx_dequeue);
2514                         recv_func_posthandle(padapter, pending_frame);
2515                 }
2516
2517                 if (cnt)
2518                         DBG_871X(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n",
2519                                 FUNC_ADPT_ARG(padapter), cnt);
2520         }
2521
2522         DBG_COUNTER(padapter->rx_logs.core_rx);
2523         ret = recv_func_prehandle(padapter, rframe);
2524
2525         if (ret == _SUCCESS) {
2526
2527                 /* check if need to enqueue into uc_swdec_pending_queue*/
2528                 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2529                         !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 &&
2530                         (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt == true) &&
2531                         psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
2532                         !psecuritypriv->busetkipkey) {
2533                         DBG_COUNTER(padapter->rx_logs.core_rx_enqueue);
2534                         rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
2535                         /* DBG_871X("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); */
2536
2537                         if (recvpriv->free_recvframe_cnt < NR_RECVFRAME/4) {
2538                                 /* to prevent from recvframe starvation, get recvframe from uc_swdec_pending_queue to free_recvframe_cnt  */
2539                                 rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
2540                                 if (rframe)
2541                                         goto do_posthandle;
2542                         }
2543                         goto exit;
2544                 }
2545
2546 do_posthandle:
2547                 ret = recv_func_posthandle(padapter, rframe);
2548         }
2549
2550 exit:
2551         return ret;
2552 }
2553
2554
2555 s32 rtw_recv_entry(union recv_frame *precvframe)
2556 {
2557         struct adapter *padapter;
2558         struct recv_priv *precvpriv;
2559         s32 ret = _SUCCESS;
2560
2561 /*      RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+rtw_recv_entry\n")); */
2562
2563         padapter = precvframe->u.hdr.adapter;
2564
2565         precvpriv = &padapter->recvpriv;
2566
2567         ret = recv_func(padapter, precvframe);
2568         if (ret == _FAIL) {
2569                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtw_recv_entry: recv_func return fail!!!\n"));
2570                 goto _recv_entry_drop;
2571         }
2572
2573
2574         precvpriv->rx_pkts++;
2575
2576         return ret;
2577
2578 _recv_entry_drop:
2579
2580         /* RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("_recv_entry_drop\n")); */
2581
2582         return ret;
2583 }
2584
2585 static void rtw_signal_stat_timer_hdl(struct timer_list *t)
2586 {
2587         struct adapter *adapter =
2588                 from_timer(adapter, t, recvpriv.signal_stat_timer);
2589         struct recv_priv *recvpriv = &adapter->recvpriv;
2590
2591         u32 tmp_s, tmp_q;
2592         u8 avg_signal_strength = 0;
2593         u8 avg_signal_qual = 0;
2594         u32 num_signal_strength = 0;
2595         u32 num_signal_qual = 0;
2596         u8 _alpha = 5; /*  this value is based on converging_constant = 5000 and sampling_interval = 1000 */
2597
2598         if (adapter->recvpriv.is_signal_dbg) {
2599                 /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
2600                 adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
2601                 adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
2602         } else {
2603
2604                 if (recvpriv->signal_strength_data.update_req == 0) {/*  update_req is clear, means we got rx */
2605                         avg_signal_strength = recvpriv->signal_strength_data.avg_val;
2606                         num_signal_strength = recvpriv->signal_strength_data.total_num;
2607                         /*  after avg_vals are acquired, we can re-stat the signal values */
2608                         recvpriv->signal_strength_data.update_req = 1;
2609                 }
2610
2611                 if (recvpriv->signal_qual_data.update_req == 0) {/*  update_req is clear, means we got rx */
2612                         avg_signal_qual = recvpriv->signal_qual_data.avg_val;
2613                         num_signal_qual = recvpriv->signal_qual_data.total_num;
2614                         /*  after avg_vals are acquired, we can re-stat the signal values */
2615                         recvpriv->signal_qual_data.update_req = 1;
2616                 }
2617
2618                 if (num_signal_strength == 0) {
2619                         if (rtw_get_on_cur_ch_time(adapter) == 0
2620                                 || jiffies_to_msecs(jiffies - rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval
2621                         ) {
2622                                 goto set_timer;
2623                         }
2624                 }
2625
2626                 if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == true
2627                         || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == false
2628                 ) {
2629                         goto set_timer;
2630                 }
2631
2632                 /* update value of signal_strength, rssi, signal_qual */
2633                 tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength);
2634                 if (tmp_s % _alpha)
2635                         tmp_s = tmp_s/_alpha + 1;
2636                 else
2637                         tmp_s = tmp_s/_alpha;
2638                 if (tmp_s > 100)
2639                         tmp_s = 100;
2640
2641                 tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual);
2642                 if (tmp_q % _alpha)
2643                         tmp_q = tmp_q/_alpha + 1;
2644                 else
2645                         tmp_q = tmp_q/_alpha;
2646                 if (tmp_q > 100)
2647                         tmp_q = 100;
2648
2649                 recvpriv->signal_strength = tmp_s;
2650                 recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
2651                 recvpriv->signal_qual = tmp_q;
2652
2653                 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2654                 DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
2655                         ", num_signal_strength:%u, num_signal_qual:%u"
2656                         ", on_cur_ch_ms:%d"
2657                         "\n"
2658                         , FUNC_ADPT_ARG(adapter)
2659                         , recvpriv->signal_strength
2660                         , recvpriv->rssi
2661                         , recvpriv->signal_qual
2662                         , num_signal_strength, num_signal_qual
2663                         , rtw_get_on_cur_ch_time(adapter) ? jiffies_to_msecs(jiffies - rtw_get_on_cur_ch_time(adapter)) : 0
2664                 );
2665                 #endif
2666         }
2667
2668 set_timer:
2669         rtw_set_signal_stat_timer(recvpriv);
2670
2671 }