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