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