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