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