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