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