net: wireless: rockchip: add rtl8822be pcie wifi driver
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8822be / core / rtw_recv.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #define _RTW_RECV_C_
21
22 #include <drv_types.h>
23 #include <hal_data.h>
24
25 #if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
26
27         #error "Shall be Linux or Windows, but not both!\n"
28
29 #endif
30
31
32 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
33 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS);
34
35 enum {
36         SIGNAL_STAT_CALC_PROFILE_0 = 0,
37         SIGNAL_STAT_CALC_PROFILE_1,
38         SIGNAL_STAT_CALC_PROFILE_MAX
39 };
40
41 u8 signal_stat_calc_profile[SIGNAL_STAT_CALC_PROFILE_MAX][2] = {
42         {4, 1}, /* Profile 0 => pre_stat : curr_stat = 4 : 1 */
43         {3, 7}  /* Profile 1 => pre_stat : curr_stat = 3 : 7 */
44 };
45
46 #ifndef RTW_SIGNAL_STATE_CALC_PROFILE
47         #define RTW_SIGNAL_STATE_CALC_PROFILE SIGNAL_STAT_CALC_PROFILE_1
48 #endif
49
50 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
51
52 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
53 {
54
55
56         _func_enter_;
57
58         _rtw_memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
59
60         _rtw_spinlock_init(&psta_recvpriv->lock);
61
62         /* for(i=0; i<MAX_RX_NUMBLKS; i++) */
63         /*      _rtw_init_queue(&psta_recvpriv->blk_strms[i]); */
64
65         _rtw_init_queue(&psta_recvpriv->defrag_q);
66
67         _func_exit_;
68
69 }
70
71 sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter)
72 {
73         sint i;
74
75         union recv_frame *precvframe;
76         sint    res = _SUCCESS;
77
78         _func_enter_;
79
80         /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
81         /* _rtw_memset((unsigned char *)precvpriv, 0, sizeof (struct  recv_priv)); */
82
83         _rtw_spinlock_init(&precvpriv->lock);
84
85         _rtw_init_queue(&precvpriv->free_recv_queue);
86         _rtw_init_queue(&precvpriv->recv_pending_queue);
87         _rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
88
89         precvpriv->adapter = padapter;
90
91         precvpriv->free_recvframe_cnt = NR_RECVFRAME;
92
93         precvpriv->sink_udpport = 0;
94         precvpriv->pre_rtp_rxseq = 0;
95         precvpriv->cur_rtp_rxseq = 0;
96
97 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
98         precvpriv->store_law_data_flag = 1;
99 #else
100         precvpriv->store_law_data_flag = 0;
101 #endif
102
103         rtw_os_recv_resource_init(precvpriv, padapter);
104
105         precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
106
107         if (precvpriv->pallocated_frame_buf == NULL) {
108                 res = _FAIL;
109                 goto exit;
110         }
111         /* _rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); */
112
113         precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
114         /* precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - */
115         /*                                              ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); */
116
117         precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
118
119
120         for (i = 0; i < NR_RECVFRAME ; i++) {
121                 _rtw_init_listhead(&(precvframe->u.list));
122
123                 rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
124
125                 res = rtw_os_recv_resource_alloc(padapter, precvframe);
126
127                 precvframe->u.hdr.len = 0;
128
129                 precvframe->u.hdr.adapter = padapter;
130                 precvframe++;
131
132         }
133
134 #ifdef CONFIG_USB_HCI
135
136         ATOMIC_SET(&(precvpriv->rx_pending_cnt), 1);
137
138         _rtw_init_sema(&precvpriv->allrxreturnevt, 0);
139
140 #endif
141
142         res = rtw_hal_init_recv_priv(padapter);
143
144 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
145         rtw_init_timer(&precvpriv->signal_stat_timer, padapter, RTW_TIMER_HDL_NAME(signal_stat));
146
147         precvpriv->signal_stat_sampling_interval = 2000; /* ms */
148         /* precvpriv->signal_stat_converging_constant = 5000; */ /* ms */
149
150         /* rtw_set_signal_stat_timer(precvpriv); */ /* move to rtw_init_drv_sw() */
151
152 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
153
154 exit:
155
156         _func_exit_;
157
158         return res;
159
160 }
161
162 void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv);
163 void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv)
164 {
165         _rtw_spinlock_free(&precvpriv->lock);
166 #ifdef CONFIG_RECV_THREAD_MODE
167         _rtw_free_sema(&precvpriv->recv_sema);
168         _rtw_free_sema(&precvpriv->terminate_recvthread_sema);
169 #endif
170
171         _rtw_spinlock_free(&precvpriv->free_recv_queue.lock);
172         _rtw_spinlock_free(&precvpriv->recv_pending_queue.lock);
173
174         _rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock);
175
176 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
177         _rtw_spinlock_free(&precvpriv->recv_buf_pending_queue.lock);
178 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
179 }
180
181 void _rtw_free_recv_priv(struct recv_priv *precvpriv)
182 {
183         _adapter        *padapter = precvpriv->adapter;
184
185         _func_enter_;
186
187         rtw_free_uc_swdec_pending_queue(padapter);
188
189         rtw_mfree_recv_priv_lock(precvpriv);
190
191         rtw_os_recv_resource_free(precvpriv);
192
193         if (precvpriv->pallocated_frame_buf)
194                 rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
195
196         rtw_hal_free_recv_priv(padapter);
197
198         _func_exit_;
199
200 }
201
202 bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset)
203 {
204 #define DBG_RFRAME_DEL_WFD_IE 0
205         u8 *ies = rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + ies_offset;
206         uint ies_len_ori = rframe->u.hdr.len - (ies - rframe->u.hdr.rx_data);
207         uint ies_len;
208
209         ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_RFRAME_DEL_WFD_IE ? __func__ : NULL);
210         rframe->u.hdr.len -= ies_len_ori - ies_len;
211
212         return ies_len_ori != ies_len;
213 }
214
215 union recv_frame *_rtw_alloc_recvframe(_queue *pfree_recv_queue)
216 {
217
218         union recv_frame  *precvframe;
219         _list   *plist, *phead;
220         _adapter *padapter;
221         struct recv_priv *precvpriv;
222         _func_enter_;
223
224         if (_rtw_queue_empty(pfree_recv_queue) == _TRUE)
225                 precvframe = NULL;
226         else {
227                 phead = get_list_head(pfree_recv_queue);
228
229                 plist = get_next(phead);
230
231                 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
232
233                 rtw_list_delete(&precvframe->u.hdr.list);
234                 padapter = precvframe->u.hdr.adapter;
235                 if (padapter != NULL) {
236                         precvpriv = &padapter->recvpriv;
237                         if (pfree_recv_queue == &precvpriv->free_recv_queue)
238                                 precvpriv->free_recvframe_cnt--;
239                 }
240         }
241
242         _func_exit_;
243
244         return precvframe;
245
246 }
247
248 union recv_frame *rtw_alloc_recvframe(_queue *pfree_recv_queue)
249 {
250         _irqL irqL;
251         union recv_frame  *precvframe;
252
253         _enter_critical_bh(&pfree_recv_queue->lock, &irqL);
254
255         precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
256
257         _exit_critical_bh(&pfree_recv_queue->lock, &irqL);
258
259         return precvframe;
260 }
261
262 void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv)
263 {
264         /* Perry: This can be removed */
265         _rtw_init_listhead(&precvframe->u.hdr.list);
266
267         precvframe->u.hdr.len = 0;
268 }
269
270 int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue)
271 {
272         _irqL irqL;
273         _adapter *padapter = precvframe->u.hdr.adapter;
274         struct recv_priv *precvpriv = &padapter->recvpriv;
275
276         _func_enter_;
277
278 #ifdef CONFIG_CONCURRENT_MODE
279         padapter = GET_PRIMARY_ADAPTER(padapter);
280         precvpriv = &padapter->recvpriv;
281         pfree_recv_queue = &precvpriv->free_recv_queue;
282         precvframe->u.hdr.adapter = padapter;
283 #endif
284
285
286         rtw_os_free_recvframe(precvframe);
287
288
289         _enter_critical_bh(&pfree_recv_queue->lock, &irqL);
290
291         rtw_list_delete(&(precvframe->u.hdr.list));
292
293         precvframe->u.hdr.len = 0;
294
295         rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
296
297         if (padapter != NULL) {
298                 if (pfree_recv_queue == &precvpriv->free_recv_queue)
299                         precvpriv->free_recvframe_cnt++;
300         }
301
302         _exit_critical_bh(&pfree_recv_queue->lock, &irqL);
303
304         _func_exit_;
305
306         return _SUCCESS;
307
308 }
309
310
311
312
313 sint _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
314 {
315
316         _adapter *padapter = precvframe->u.hdr.adapter;
317         struct recv_priv *precvpriv = &padapter->recvpriv;
318
319         _func_enter_;
320
321         /* _rtw_init_listhead(&(precvframe->u.hdr.list)); */
322         rtw_list_delete(&(precvframe->u.hdr.list));
323
324
325         rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue));
326
327         if (padapter != NULL) {
328                 if (queue == &precvpriv->free_recv_queue)
329                         precvpriv->free_recvframe_cnt++;
330         }
331
332         _func_exit_;
333
334         return _SUCCESS;
335 }
336
337 sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
338 {
339         sint ret;
340         _irqL irqL;
341
342         /* _spinlock(&pfree_recv_queue->lock); */
343         _enter_critical_bh(&queue->lock, &irqL);
344         ret = _rtw_enqueue_recvframe(precvframe, queue);
345         /* _rtw_spinunlock(&pfree_recv_queue->lock); */
346         _exit_critical_bh(&queue->lock, &irqL);
347
348         return ret;
349 }
350
351 /*
352 sint    rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
353 {
354         return rtw_free_recvframe(precvframe, queue);
355 }
356 */
357
358
359
360
361 /*
362 caller : defrag ; recvframe_chk_defrag in recv_thread  (passive)
363 pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
364
365 using spinlock to protect
366
367 */
368
369 void rtw_free_recvframe_queue(_queue *pframequeue,  _queue *pfree_recv_queue)
370 {
371         union   recv_frame      *precvframe;
372         _list   *plist, *phead;
373
374         _func_enter_;
375         _rtw_spinlock(&pframequeue->lock);
376
377         phead = get_list_head(pframequeue);
378         plist = get_next(phead);
379
380         while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
381                 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
382
383                 plist = get_next(plist);
384
385                 /* rtw_list_delete(&precvframe->u.hdr.list); */ /* will do this in rtw_free_recvframe() */
386
387                 rtw_free_recvframe(precvframe, pfree_recv_queue);
388         }
389
390         _rtw_spinunlock(&pframequeue->lock);
391
392         _func_exit_;
393
394 }
395
396 u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter)
397 {
398         u32 cnt = 0;
399         union recv_frame *pending_frame;
400         while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
401                 rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
402                 cnt++;
403         }
404
405         if (cnt)
406                 RTW_INFO(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt);
407
408         return cnt;
409 }
410
411
412 sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue)
413 {
414         _irqL irqL;
415
416         _enter_critical_bh(&queue->lock, &irqL);
417
418         rtw_list_delete(&precvbuf->list);
419         rtw_list_insert_head(&precvbuf->list, get_list_head(queue));
420
421         _exit_critical_bh(&queue->lock, &irqL);
422
423         return _SUCCESS;
424 }
425
426 sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue)
427 {
428         _irqL irqL;
429 #ifdef CONFIG_SDIO_HCI
430         _enter_critical_bh(&queue->lock, &irqL);
431 #else
432         _enter_critical_ex(&queue->lock, &irqL);
433 #endif/*#ifdef CONFIG_SDIO_HCI*/
434
435         rtw_list_delete(&precvbuf->list);
436
437         rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
438 #ifdef CONFIG_SDIO_HCI
439         _exit_critical_bh(&queue->lock, &irqL);
440 #else
441         _exit_critical_ex(&queue->lock, &irqL);
442 #endif/*#ifdef CONFIG_SDIO_HCI*/
443         return _SUCCESS;
444
445 }
446
447 struct recv_buf *rtw_dequeue_recvbuf(_queue *queue)
448 {
449         _irqL irqL;
450         struct recv_buf *precvbuf;
451         _list   *plist, *phead;
452
453 #ifdef CONFIG_SDIO_HCI
454         _enter_critical_bh(&queue->lock, &irqL);
455 #else
456         _enter_critical_ex(&queue->lock, &irqL);
457 #endif/*#ifdef CONFIG_SDIO_HCI*/
458
459         if (_rtw_queue_empty(queue) == _TRUE)
460                 precvbuf = NULL;
461         else {
462                 phead = get_list_head(queue);
463
464                 plist = get_next(phead);
465
466                 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
467
468                 rtw_list_delete(&precvbuf->list);
469
470         }
471
472 #ifdef CONFIG_SDIO_HCI
473         _exit_critical_bh(&queue->lock, &irqL);
474 #else
475         _exit_critical_ex(&queue->lock, &irqL);
476 #endif/*#ifdef CONFIG_SDIO_HCI*/
477
478         return precvbuf;
479
480 }
481
482 sint recvframe_chkmic(_adapter *adapter,  union recv_frame *precvframe);
483 sint recvframe_chkmic(_adapter *adapter,  union recv_frame *precvframe)
484 {
485
486         sint    i, res = _SUCCESS;
487         u32     datalen;
488         u8      miccode[8];
489         u8      bmic_err = _FALSE, brpt_micerror = _TRUE;
490         u8      *pframe, *payload, *pframemic;
491         u8      *mickey;
492         /* u8   *iv,rxdata_key_idx=0; */
493         struct  sta_info                *stainfo;
494         struct  rx_pkt_attrib   *prxattrib = &precvframe->u.hdr.attrib;
495         struct  security_priv   *psecuritypriv = &adapter->securitypriv;
496
497         struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
498         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
499         _func_enter_;
500
501         stainfo = rtw_get_stainfo(&adapter->stapriv , &prxattrib->ta[0]);
502
503         if (prxattrib->encrypt == _TKIP_) {
504                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic:prxattrib->encrypt ==_TKIP_\n"));
505                 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",
506                         prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2], prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5]));
507
508                 /* calculate mic code */
509                 if (stainfo != NULL) {
510                         if (IS_MCAST(prxattrib->ra)) {
511                                 /* mickey=&psecuritypriv->dot118021XGrprxmickey.skey[0]; */
512                                 /* iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; */
513                                 /* rxdata_key_idx =( ((iv[3])>>6)&0x3) ; */
514                                 mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
515
516                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic: bcmc key\n"));
517                                 /* RTW_INFO("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d),pmlmeinfo->key_index(%d) ,recv key_id(%d)\n", */
518                                 /*                                                              psecuritypriv->dot118021XGrpKeyid,pmlmeinfo->key_index,rxdata_key_idx); */
519
520                                 if (psecuritypriv->binstallGrpkey == _FALSE) {
521                                         res = _FAIL;
522                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"));
523                                         RTW_INFO("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
524                                         goto exit;
525                                 }
526                         } else {
527                                 mickey = &stainfo->dot11tkiprxmickey.skey[0];
528                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic: unicast key\n"));
529                         }
530
531                         datalen = precvframe->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8; /* icv_len included the mic code */
532                         pframe = precvframe->u.hdr.rx_data;
533                         payload = pframe + prxattrib->hdrlen + prxattrib->iv_len;
534
535                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n", prxattrib->iv_len, prxattrib->icv_len));
536
537                         /* rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); */ /* care the length of the data */
538
539                         rtw_seccalctkipmic(mickey, pframe, payload, datalen , &miccode[0], (unsigned char)prxattrib->priority); /* care the length of the data */
540
541                         pframemic = payload + datalen;
542
543                         bmic_err = _FALSE;
544
545                         for (i = 0; i < 8; i++) {
546                                 if (miccode[i] != *(pframemic + i)) {
547                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ", i, miccode[i], i, *(pframemic + i)));
548                                         bmic_err = _TRUE;
549                                 }
550                         }
551
552
553                         if (bmic_err == _TRUE) {
554
555                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n *(pframemic-8)-*(pframemic-1)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
556                                         *(pframemic - 8), *(pframemic - 7), *(pframemic - 6), *(pframemic - 5), *(pframemic - 4), *(pframemic - 3), *(pframemic - 2), *(pframemic - 1)));
557                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n *(pframemic-16)-*(pframemic-9)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
558                                         *(pframemic - 16), *(pframemic - 15), *(pframemic - 14), *(pframemic - 13), *(pframemic - 12), *(pframemic - 11), *(pframemic - 10), *(pframemic - 9)));
559
560                                 {
561                                         uint i;
562                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet (len=%d)======\n", precvframe->u.hdr.len));
563                                         for (i = 0; i < precvframe->u.hdr.len; i = i + 8) {
564                                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x",
565                                                         *(precvframe->u.hdr.rx_data + i), *(precvframe->u.hdr.rx_data + i + 1),
566                                                         *(precvframe->u.hdr.rx_data + i + 2), *(precvframe->u.hdr.rx_data + i + 3),
567                                                         *(precvframe->u.hdr.rx_data + i + 4), *(precvframe->u.hdr.rx_data + i + 5),
568                                                         *(precvframe->u.hdr.rx_data + i + 6), *(precvframe->u.hdr.rx_data + i + 7)));
569                                         }
570                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet end [len=%d]======\n", precvframe->u.hdr.len));
571                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n hrdlen=%d,\n", prxattrib->hdrlen));
572                                 }
573
574                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ra=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey=%d ",
575                                         prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2],
576                                         prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5], psecuritypriv->binstallGrpkey));
577
578                                 /* double check key_index for some timing issue , */
579                                 /* cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
580                                 if ((IS_MCAST(prxattrib->ra) == _TRUE)  && (prxattrib->key_index != pmlmeinfo->key_index))
581                                         brpt_micerror = _FALSE;
582
583                                 if ((prxattrib->bdecrypted == _TRUE) && (brpt_micerror == _TRUE)) {
584                                         rtw_handle_tkip_mic_err(adapter, stainfo, (u8)IS_MCAST(prxattrib->ra));
585                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted=%d ", prxattrib->bdecrypted));
586                                         RTW_INFO(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
587                                 } else {
588                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted=%d ", prxattrib->bdecrypted));
589                                         RTW_INFO(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
590                                 }
591
592                                 res = _FAIL;
593
594                         } else {
595                                 /* mic checked ok */
596                                 if ((psecuritypriv->bcheck_grpkey == _FALSE) && (IS_MCAST(prxattrib->ra) == _TRUE)) {
597                                         psecuritypriv->bcheck_grpkey = _TRUE;
598                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("psecuritypriv->bcheck_grpkey =_TRUE"));
599                                 }
600                         }
601
602                 } else
603                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n"));
604
605                 recvframe_pull_tail(precvframe, 8);
606
607         }
608
609 exit:
610
611         _func_exit_;
612
613         return res;
614
615 }
616
617 /*#define DBG_RX_SW_DECRYPTOR*/
618
619 /* decrypt and set the ivlen,icvlen of the recv_frame */
620 union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame);
621 union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame)
622 {
623
624         struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
625         struct security_priv *psecuritypriv = &padapter->securitypriv;
626         union recv_frame *return_packet = precv_frame;
627         u32      res = _SUCCESS;
628
629         _func_enter_;
630
631         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt);
632
633         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("prxstat->decrypted=%x prxattrib->encrypt = 0x%03x\n", prxattrib->bdecrypted, prxattrib->encrypt));
634
635         if (prxattrib->encrypt > 0) {
636                 u8 *iv = precv_frame->u.hdr.rx_data + prxattrib->hdrlen;
637                 prxattrib->key_index = (((iv[3]) >> 6) & 0x3) ;
638
639                 if (prxattrib->key_index > WEP_KEYS) {
640                         RTW_INFO("prxattrib->key_index(%d) > WEP_KEYS\n", prxattrib->key_index);
641
642                         switch (prxattrib->encrypt) {
643                         case _WEP40_:
644                         case _WEP104_:
645                                 prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
646                                 break;
647                         case _TKIP_:
648                         case _AES_:
649                         default:
650                                 prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
651                                 break;
652                         }
653                 }
654         }
655
656         if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt == _TRUE))) {
657
658 #ifdef CONFIG_CONCURRENT_MODE
659                 if (!IS_MCAST(prxattrib->ra)) /* bc/mc packets use sw decryption for concurrent mode */
660 #endif
661                         psecuritypriv->hw_decrypted = _FALSE;
662
663 #ifdef DBG_RX_SW_DECRYPTOR
664                 RTW_INFO(ADPT_FMT" - sec_type:%s DO SW decryption\n",
665                         ADPT_ARG(padapter), security_type_str(prxattrib->encrypt));
666 #endif
667
668 #ifdef DBG_RX_DECRYPTOR
669                 RTW_INFO("[%s] %d:prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n",
670                          __FUNCTION__,
671                          __LINE__,
672                          prxattrib->bdecrypted,
673                          prxattrib->encrypt,
674                          psecuritypriv->hw_decrypted);
675 #endif
676
677                 switch (prxattrib->encrypt) {
678                 case _WEP40_:
679                 case _WEP104_:
680                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep);
681                         rtw_wep_decrypt(padapter, (u8 *)precv_frame);
682                         break;
683                 case _TKIP_:
684                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip);
685                         res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
686                         break;
687                 case _AES_:
688                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes);
689                         res = rtw_aes_decrypt(padapter, (u8 *)precv_frame);
690                         break;
691 #ifdef CONFIG_WAPI_SUPPORT
692                 case _SMS4_:
693                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wapi);
694                         rtw_sms4_decrypt(padapter, (u8 *)precv_frame);
695                         break;
696 #endif
697                 default:
698                         break;
699                 }
700         } else if (prxattrib->bdecrypted == 1
701                    && prxattrib->encrypt > 0
702                 && (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)
703                   ) {
704 #if 0
705                 if ((prxstat->icv == 1) && (prxattrib->encrypt != _AES_)) {
706                         psecuritypriv->hw_decrypted = _FALSE;
707
708                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("psecuritypriv->hw_decrypted=_FALSE"));
709
710                         rtw_free_recvframe(precv_frame, &padapter->recvpriv.free_recv_queue);
711
712                         return_packet = NULL;
713
714                 } else
715 #endif
716                 {
717                         DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw);
718
719                         psecuritypriv->hw_decrypted = _TRUE;
720 #ifdef DBG_RX_DECRYPTOR
721                         RTW_INFO("[%s] %d:prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n",
722                                  __FUNCTION__,
723                                  __LINE__,
724                                  prxattrib->bdecrypted,
725                                  prxattrib->encrypt,
726                                  psecuritypriv->hw_decrypted);
727
728 #endif
729                 }
730         } else {
731                 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown);
732 #ifdef DBG_RX_DECRYPTOR
733                 RTW_INFO("[%s] %d:prxstat->bdecrypted:%d,  prxattrib->encrypt:%d,  Setting psecuritypriv->hw_decrypted = %d\n",
734                          __FUNCTION__,
735                          __LINE__,
736                          prxattrib->bdecrypted,
737                          prxattrib->encrypt,
738                          psecuritypriv->hw_decrypted);
739 #endif
740         }
741
742         if (res == _FAIL) {
743                 rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
744                 return_packet = NULL;
745         } else
746                 prxattrib->bdecrypted = _TRUE;
747         /* recvframe_chkmic(adapter, precv_frame);   */ /* move to recvframme_defrag function */
748
749         _func_exit_;
750
751         return return_packet;
752
753 }
754 /* ###set the security information in the recv_frame */
755 union recv_frame *portctrl(_adapter *adapter, union recv_frame *precv_frame);
756 union recv_frame *portctrl(_adapter *adapter, union recv_frame *precv_frame)
757 {
758         u8 *psta_addr = NULL;
759         u8 *ptr;
760         uint  auth_alg;
761         struct recv_frame_hdr *pfhdr;
762         struct sta_info *psta;
763         struct sta_priv *pstapriv ;
764         union recv_frame *prtnframe;
765         u16     ether_type = 0;
766         u16  eapol_type = 0x888e;/* for Funia BD's WPA issue  */
767         struct rx_pkt_attrib *pattrib;
768
769         _func_enter_;
770
771         pstapriv = &adapter->stapriv;
772
773         auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
774
775         ptr = get_recvframe_data(precv_frame);
776         pfhdr = &precv_frame->u.hdr;
777         pattrib = &pfhdr->attrib;
778         psta_addr = pattrib->ta;
779
780         prtnframe = NULL;
781
782         psta = rtw_get_stainfo(pstapriv, psta_addr);
783
784         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm));
785
786         if (auth_alg == dot11AuthAlgrthm_8021X) {
787                 if ((psta != NULL) && (psta->ieee8021x_blocked)) {
788                         /* blocked */
789                         /* only accept EAPOL frame */
790                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n"));
791
792                         prtnframe = precv_frame;
793
794                         /* get ether_type */
795                         ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
796                         _rtw_memcpy(&ether_type, ptr, 2);
797                         ether_type = ntohs((unsigned short)ether_type);
798
799                         if (ether_type == eapol_type)
800                                 prtnframe = precv_frame;
801                         else {
802                                 /* free this frame */
803                                 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
804                                 prtnframe = NULL;
805                         }
806                 } else {
807                         /* allowed */
808                         /* check decryption status, and decrypt the frame if needed */
809                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==0\n"));
810                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:precv_frame->hdr.attrib.privacy=%x\n", precv_frame->u.hdr.attrib.privacy));
811
812                         if (pattrib->bdecrypted == 0)
813                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:prxstat->decrypted=%x\n", pattrib->bdecrypted));
814
815                         prtnframe = precv_frame;
816                         /* check is the EAPOL frame or not (Rekey) */
817                         /* if(ether_type == eapol_type){ */
818                         /*      RT_TRACE(_module_rtl871x_recv_c_,_drv_notice_,("########portctrl:ether_type == 0x888e\n")); */
819                         /* check Rekey */
820
821                         /*      prtnframe=precv_frame; */
822                         /* } */
823                         /* else{ */
824                         /*      RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:ether_type=0x%04x\n", ether_type)); */
825                         /* } */
826                 }
827         } else
828                 prtnframe = precv_frame;
829
830         _func_exit_;
831
832         return prtnframe;
833
834 }
835
836 sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache);
837 sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache)
838 {
839         sint tid = precv_frame->u.hdr.attrib.priority;
840
841         u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) |
842                        (precv_frame->u.hdr.attrib.frag_num & 0xf);
843
844         _func_enter_;
845
846         if (tid > 15) {
847                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl=0x%x, tid=0x%x\n", seq_ctrl, tid));
848
849                 return _FAIL;
850         }
851
852         if (1) { /* if(bretry) */
853                 if (seq_ctrl == prxcache->tid_rxseq[tid]) {
854                         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]));
855                         /* for non-AMPDU case   */
856                         precv_frame->u.hdr.psta->sta_stats.duplicate_cnt++;
857
858                         if (precv_frame->u.hdr.psta->sta_stats.duplicate_cnt % 100 == 0)
859                                 RTW_INFO("%s: seq=%d\n", __func__, precv_frame->u.hdr.attrib.seq_num);
860
861                         return _FAIL;
862                 }
863         }
864
865         prxcache->tid_rxseq[tid] = seq_ctrl;
866
867         _func_exit_;
868
869         return _SUCCESS;
870
871 }
872
873 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame);
874 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame)
875 {
876 #ifdef CONFIG_AP_MODE
877         unsigned char pwrbit;
878         u8 *ptr = precv_frame->u.hdr.rx_data;
879         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
880         struct sta_priv *pstapriv = &padapter->stapriv;
881         struct sta_info *psta = NULL;
882
883         psta = rtw_get_stainfo(pstapriv, pattrib->src);
884
885         pwrbit = GetPwrMgt(ptr);
886
887         if (psta) {
888                 if (pwrbit) {
889                         if (!(psta->state & WIFI_SLEEP_STATE)) {
890                                 /* psta->state |= WIFI_SLEEP_STATE; */
891                                 /* pstapriv->sta_dz_bitmap |= BIT(psta->aid); */
892
893                                 stop_sta_xmit(padapter, psta);
894
895                                 /* RTW_INFO("to sleep, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); */
896                         }
897                 } else {
898                         if (psta->state & WIFI_SLEEP_STATE) {
899                                 /* psta->state ^= WIFI_SLEEP_STATE; */
900                                 /* pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); */
901
902                                 wakeup_sta_to_xmit(padapter, psta);
903
904                                 /* RTW_INFO("to wakeup, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap); */
905                         }
906                 }
907
908         }
909
910 #endif
911 }
912
913 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
914 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame)
915 {
916 #ifdef CONFIG_AP_MODE
917         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
918         struct sta_priv *pstapriv = &padapter->stapriv;
919         struct sta_info *psta = NULL;
920
921         psta = rtw_get_stainfo(pstapriv, pattrib->src);
922
923         if (!psta)
924                 return;
925
926 #ifdef CONFIG_TDLS
927         if (!(psta->tdls_sta_state & TDLS_LINKED_STATE)) {
928 #endif /* CONFIG_TDLS */
929
930                 if (!psta->qos_option)
931                         return;
932
933                 if (!(psta->qos_info & 0xf))
934                         return;
935
936 #ifdef CONFIG_TDLS
937         }
938 #endif /* CONFIG_TDLS            */
939
940         if (psta->state & WIFI_SLEEP_STATE) {
941                 u8 wmmps_ac = 0;
942
943                 switch (pattrib->priority) {
944                 case 1:
945                 case 2:
946                         wmmps_ac = psta->uapsd_bk & BIT(1);
947                         break;
948                 case 4:
949                 case 5:
950                         wmmps_ac = psta->uapsd_vi & BIT(1);
951                         break;
952                 case 6:
953                 case 7:
954                         wmmps_ac = psta->uapsd_vo & BIT(1);
955                         break;
956                 case 0:
957                 case 3:
958                 default:
959                         wmmps_ac = psta->uapsd_be & BIT(1);
960                         break;
961                 }
962
963                 if (wmmps_ac) {
964                         if (psta->sleepq_ac_len > 0) {
965                                 /* process received triggered frame */
966                                 xmit_delivery_enabled_frames(padapter, psta);
967                         } else {
968                                 /* issue one qos null frame with More data bit = 0 and the EOSP bit set (=1) */
969                                 issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0);
970                         }
971                 }
972
973         }
974
975
976 #endif
977
978 }
979
980 #ifdef CONFIG_TDLS
981 sint OnTDLS(_adapter *adapter, union recv_frame *precv_frame)
982 {
983         struct rx_pkt_attrib    *pattrib = &precv_frame->u.hdr.attrib;
984         sint ret = _SUCCESS;
985         u8 *paction = get_recvframe_data(precv_frame);
986         u8 category_field = 1;
987 #ifdef CONFIG_WFD
988         u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a };
989 #endif /* CONFIG_WFD */
990         struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
991
992         /* point to action field */
993         paction += pattrib->hdrlen
994                    + pattrib->iv_len
995                    + SNAP_SIZE
996                    + ETH_TYPE_LEN
997                    + PAYLOAD_TYPE_LEN
998                    + category_field;
999
1000         RTW_INFO("[TDLS] Recv %s from "MAC_FMT" with SeqNum = %d\n", rtw_tdls_action_txt(*paction), MAC_ARG(pattrib->src), GetSequence(get_recvframe_data(precv_frame)));
1001
1002         if (hal_chk_wl_func(adapter, WL_FUNC_TDLS) == _FALSE) {
1003                 RTW_INFO("Ignore tdls frame since hal doesn't support tdls\n");
1004                 ret = _FAIL;
1005                 return ret;
1006         }
1007
1008         if (ptdlsinfo->tdls_enable == _FALSE) {
1009                 RTW_INFO("recv tdls frame, "
1010                          "but tdls haven't enabled\n");
1011                 ret = _FAIL;
1012                 return ret;
1013         }
1014
1015         switch (*paction) {
1016         case TDLS_SETUP_REQUEST:
1017                 ret = On_TDLS_Setup_Req(adapter, precv_frame);
1018                 break;
1019         case TDLS_SETUP_RESPONSE:
1020                 ret = On_TDLS_Setup_Rsp(adapter, precv_frame);
1021                 break;
1022         case TDLS_SETUP_CONFIRM:
1023                 ret = On_TDLS_Setup_Cfm(adapter, precv_frame);
1024                 break;
1025         case TDLS_TEARDOWN:
1026                 ret = On_TDLS_Teardown(adapter, precv_frame);
1027                 break;
1028         case TDLS_DISCOVERY_REQUEST:
1029                 ret = On_TDLS_Dis_Req(adapter, precv_frame);
1030                 break;
1031         case TDLS_PEER_TRAFFIC_INDICATION:
1032                 ret = On_TDLS_Peer_Traffic_Indication(adapter, precv_frame);
1033                 break;
1034         case TDLS_PEER_TRAFFIC_RESPONSE:
1035                 ret = On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame);
1036                 break;
1037 #ifdef CONFIG_TDLS_CH_SW
1038         case TDLS_CHANNEL_SWITCH_REQUEST:
1039                 ret = On_TDLS_Ch_Switch_Req(adapter, precv_frame);
1040                 break;
1041         case TDLS_CHANNEL_SWITCH_RESPONSE:
1042                 ret = On_TDLS_Ch_Switch_Rsp(adapter, precv_frame);
1043                 break;
1044 #endif
1045 #ifdef CONFIG_WFD
1046         /* First byte of WFA OUI */
1047         case 0x50:
1048                 if (_rtw_memcmp(WFA_OUI, paction, 3)) {
1049                         /* Probe request frame */
1050                         if (*(paction + 3) == 0x04) {
1051                                 /* WFDTDLS: for sigma test, do not setup direct link automatically */
1052                                 ptdlsinfo->dev_discovered = _TRUE;
1053                                 RTW_INFO("recv tunneled probe request frame\n");
1054                                 issue_tunneled_probe_rsp(adapter, precv_frame);
1055                         }
1056                         /* Probe response frame */
1057                         if (*(paction + 3) == 0x05) {
1058                                 /* WFDTDLS: for sigma test, do not setup direct link automatically */
1059                                 ptdlsinfo->dev_discovered = _TRUE;
1060                                 RTW_INFO("recv tunneled probe response frame\n");
1061                         }
1062                 }
1063                 break;
1064 #endif /* CONFIG_WFD */
1065         default:
1066                 RTW_INFO("receive TDLS frame %d but not support\n", *paction);
1067                 ret = _FAIL;
1068                 break;
1069         }
1070
1071 exit:
1072         return ret;
1073
1074 }
1075 #endif /* CONFIG_TDLS */
1076
1077 void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta);
1078 void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta)
1079 {
1080         int     sz;
1081         struct sta_info         *psta = NULL;
1082         struct stainfo_stats    *pstats = NULL;
1083         struct rx_pkt_attrib    *pattrib = &prframe->u.hdr.attrib;
1084         struct recv_priv                *precvpriv = &padapter->recvpriv;
1085         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
1086         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
1087
1088         sz = get_recvframe_len(prframe);
1089         precvpriv->rx_bytes += sz;
1090
1091         padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
1092
1093         if ((!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst)))
1094                 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
1095
1096         if (sta)
1097                 psta = sta;
1098         else
1099                 psta = prframe->u.hdr.psta;
1100
1101         if (psta) {
1102                 pstats = &psta->sta_stats;
1103
1104                 pstats->rx_data_pkts++;
1105                 pstats->rx_bytes += sz;
1106
1107                 pstats->rxratecnt[pattrib->data_rate]++;
1108                 /*record rx packets for every tid*/
1109                 pstats->rx_data_qos_pkts[pattrib->priority]++;
1110
1111 #ifdef CONFIG_TDLS
1112                 if (psta->tdls_sta_state & TDLS_LINKED_STATE) {
1113                         struct sta_info *pap_sta = NULL;
1114                         pap_sta = rtw_get_stainfo(&padapter->stapriv, get_bssid(&padapter->mlmepriv));
1115                         if (pap_sta) {
1116                                 pstats = &pap_sta->sta_stats;
1117                                 pstats->rx_data_pkts++;
1118                                 pstats->rx_bytes += sz;
1119                         }
1120                 }
1121 #endif /* CONFIG_TDLS */
1122         }
1123
1124 #ifdef CONFIG_CHECK_LEAVE_LPS
1125         traffic_check_for_leave_lps(padapter, _FALSE, 0);
1126 #endif /* CONFIG_LPS */
1127
1128 }
1129
1130 sint sta2sta_data_frame(
1131         _adapter *adapter,
1132         union recv_frame *precv_frame,
1133         struct sta_info **psta
1134 );
1135 sint sta2sta_data_frame(
1136         _adapter *adapter,
1137         union recv_frame *precv_frame,
1138         struct sta_info **psta
1139 )
1140 {
1141         u8 *ptr = precv_frame->u.hdr.rx_data;
1142         sint ret = _SUCCESS;
1143         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1144         struct  sta_priv                *pstapriv = &adapter->stapriv;
1145         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
1146         u8 *mybssid  = get_bssid(pmlmepriv);
1147         u8 *myhwaddr = adapter_mac_addr(adapter);
1148         u8 *sta_addr = NULL;
1149         sint bmcast = IS_MCAST(pattrib->dst);
1150
1151 #ifdef CONFIG_TDLS
1152         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1153 #ifdef CONFIG_TDLS_CH_SW
1154         struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
1155 #endif
1156         struct sta_info *ptdls_sta = NULL;
1157         u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
1158         /* frame body located after [+2]: ether-type, [+1]: payload type */
1159         u8 *pframe_body = psnap_type + 2 + 1;
1160 #endif
1161
1162         _func_enter_;
1163
1164         /* RTW_INFO("[%s] %d, seqnum:%d\n", __FUNCTION__, __LINE__, pattrib->seq_num); */
1165
1166         if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1167             (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1168
1169                 /* filter packets that SA is myself or multicast or broadcast */
1170                 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1171                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA==myself\n"));
1172                         ret = _FAIL;
1173                         goto exit;
1174                 }
1175
1176                 if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN))    && (!bmcast)) {
1177                         ret = _FAIL;
1178                         goto exit;
1179                 }
1180
1181                 if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1182                     _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1183                     (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1184                         ret = _FAIL;
1185                         goto exit;
1186                 }
1187
1188                 sta_addr = pattrib->src;
1189
1190         } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
1191 #ifdef CONFIG_TDLS
1192
1193                 /* direct link data transfer */
1194                 if (ptdlsinfo->link_established == _TRUE) {
1195                         ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
1196                         if (ptdls_sta == NULL) {
1197                                 ret = _FAIL;
1198                                 goto exit;
1199                         } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1200                                 /* filter packets that SA is myself or multicast or broadcast */
1201                                 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1202                                         ret = _FAIL;
1203                                         goto exit;
1204                                 }
1205                                 /* da should be for me */
1206                                 if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1207                                         ret = _FAIL;
1208                                         goto exit;
1209                                 }
1210                                 /* check BSSID */
1211                                 if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1212                                     _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1213                                     (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1214                                         ret = _FAIL;
1215                                         goto exit;
1216                                 }
1217
1218 #ifdef CONFIG_TDLS_CH_SW
1219                                 if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) {
1220                                         if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) {
1221                                                 pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE;
1222                                                 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
1223                                                         _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
1224                                                 /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */
1225                                         }
1226                                 }
1227 #endif
1228
1229                                 /* process UAPSD tdls sta */
1230                                 process_pwrbit_data(adapter, precv_frame);
1231
1232                                 /* if NULL-frame, check pwrbit */
1233                                 if ((GetFrameSubType(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) {
1234                                         /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */
1235                                         if (GetPwrMgt(ptr)) {
1236                                                 /* it would be triggered when we are off channel and receiving NULL DATA */
1237                                                 /* we can confirm that peer STA is at off channel */
1238                                                 RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n");
1239                                                 /* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */
1240                                         }
1241
1242                                         /* TODO: Updated BSSID's seq. */
1243                                         /* RTW_INFO("drop Null Data\n"); */
1244                                         ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
1245                                         ret = _FAIL;
1246                                         goto exit;
1247                                 }
1248
1249                                 /* receive some of all TDLS management frames, process it at ON_TDLS */
1250                                 if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) {
1251                                         ret = OnTDLS(adapter, precv_frame);
1252                                         goto exit;
1253                                 }
1254
1255                                 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE)
1256                                         process_wmmps_data(adapter, precv_frame);
1257
1258                                 ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
1259
1260                         }
1261
1262                         sta_addr = pattrib->src;
1263
1264                 } else
1265 #endif /* CONFIG_TDLS */
1266                 {
1267                         /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
1268                         if (!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
1269                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("bssid != TA under STATION_MODE; drop pkt\n"));
1270                                 ret = _FAIL;
1271                                 goto exit;
1272                         }
1273
1274                         sta_addr = pattrib->bssid;
1275                 }
1276
1277         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1278                 if (bmcast) {
1279                         /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */
1280                         if (!IS_MCAST(pattrib->bssid)) {
1281                                 ret = _FAIL;
1282                                 goto exit;
1283                         }
1284                 } else { /* not mc-frame */
1285                         /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
1286                         if (!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
1287                                 ret = _FAIL;
1288                                 goto exit;
1289                         }
1290
1291                         sta_addr = pattrib->src;
1292                 }
1293
1294         } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) {
1295                 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1296                 _rtw_memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
1297                 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1298                 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1299                 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1300
1301                 sta_addr = mybssid;
1302         } else
1303                 ret  = _FAIL;
1304
1305
1306
1307         if (bmcast)
1308                 *psta = rtw_get_bcmc_stainfo(adapter);
1309         else
1310                 *psta = rtw_get_stainfo(pstapriv, sta_addr); /* get ap_info */
1311
1312 #ifdef CONFIG_TDLS
1313         if (ptdls_sta != NULL)
1314                 *psta = ptdls_sta;
1315 #endif /* CONFIG_TDLS */
1316
1317         if (*psta == NULL) {
1318                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under sta2sta_data_frame ; drop pkt\n"));
1319 #ifdef CONFIG_MP_INCLUDED
1320                 if (adapter->registrypriv.mp_mode == 1) {
1321                         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1322                                 adapter->mppriv.rx_pktloss++;
1323                 }
1324 #endif
1325                 ret = _FAIL;
1326                 goto exit;
1327         }
1328
1329 exit:
1330         _func_exit_;
1331         return ret;
1332
1333 }
1334
1335 sint ap2sta_data_frame(
1336         _adapter *adapter,
1337         union recv_frame *precv_frame,
1338         struct sta_info **psta);
1339 sint ap2sta_data_frame(
1340         _adapter *adapter,
1341         union recv_frame *precv_frame,
1342         struct sta_info **psta)
1343 {
1344         u8 *ptr = precv_frame->u.hdr.rx_data;
1345         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1346         sint ret = _SUCCESS;
1347         struct  sta_priv                *pstapriv = &adapter->stapriv;
1348         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
1349         u8 *mybssid  = get_bssid(pmlmepriv);
1350         u8 *myhwaddr = adapter_mac_addr(adapter);
1351         sint bmcast = IS_MCAST(pattrib->dst);
1352
1353         _func_enter_;
1354
1355         if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1356             && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE
1357                 || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
1358            ) {
1359
1360                 /* filter packets that SA is myself or multicast or broadcast */
1361                 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1362                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA==myself\n"));
1363 #ifdef DBG_RX_DROP_FRAME
1364                         RTW_INFO("DBG_RX_DROP_FRAME %s SA="MAC_FMT", myhwaddr="MAC_FMT"\n",
1365                                 __FUNCTION__, MAC_ARG(pattrib->src), MAC_ARG(myhwaddr));
1366 #endif
1367                         ret = _FAIL;
1368                         goto exit;
1369                 }
1370
1371                 /* da should be for me */
1372                 if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1373                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1374                                 (" ap2sta_data_frame:  compare DA fail; DA="MAC_FMT"\n", MAC_ARG(pattrib->dst)));
1375 #ifdef DBG_RX_DROP_FRAME
1376                         RTW_INFO("DBG_RX_DROP_FRAME %s DA="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst));
1377 #endif
1378                         ret = _FAIL;
1379                         goto exit;
1380                 }
1381
1382
1383                 /* check BSSID */
1384                 if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1385                     _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1386                     (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1387                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1388                                 (" ap2sta_data_frame:  compare BSSID fail ; BSSID="MAC_FMT"\n", MAC_ARG(pattrib->bssid)));
1389                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("mybssid="MAC_FMT"\n", MAC_ARG(mybssid)));
1390 #ifdef DBG_RX_DROP_FRAME
1391                         RTW_INFO("DBG_RX_DROP_FRAME %s BSSID="MAC_FMT", mybssid="MAC_FMT"\n",
1392                                 __func__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
1393 #endif
1394
1395                         if (!bmcast) {
1396                                 RTW_INFO(ADPT_FMT" -issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", ADPT_ARG(adapter), MAC_ARG(pattrib->bssid));
1397                                 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1398                         }
1399
1400                         ret = _FAIL;
1401                         goto exit;
1402                 }
1403
1404                 if (bmcast)
1405                         *psta = rtw_get_bcmc_stainfo(adapter);
1406                 else
1407                         *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get ap_info */
1408
1409                 if (*psta == NULL) {
1410                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ap2sta: can't get psta under STATION_MODE ; drop pkt\n"));
1411 #ifdef DBG_RX_DROP_FRAME
1412                         RTW_INFO("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __FUNCTION__);
1413 #endif
1414                         ret = _FAIL;
1415                         goto exit;
1416                 }
1417
1418                 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1419                 }
1420
1421                 if (GetFrameSubType(ptr) & BIT(6)) {
1422                         /* No data, will not indicate to upper layer, temporily count it here */
1423                         count_rx_stats(adapter, precv_frame, *psta);
1424                         ret = RTW_RX_HANDLED;
1425                         goto exit;
1426                 }
1427
1428         } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1429                    (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
1430                 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1431                 _rtw_memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
1432                 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1433                 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1434                 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1435
1436                 /*  */
1437                 if (adapter->mppriv.bRTWSmbCfg == _FALSE)
1438                         _rtw_memcpy(pattrib->bssid,  mybssid, ETH_ALEN);
1439
1440
1441                 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1442                 if (*psta == NULL) {
1443                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n"));
1444 #ifdef DBG_RX_DROP_FRAME
1445                         RTW_INFO("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __FUNCTION__);
1446 #endif
1447                         ret = _FAIL;
1448                         goto exit;
1449                 }
1450
1451
1452         } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1453                 /* Special case */
1454                 ret = RTW_RX_HANDLED;
1455                 goto exit;
1456         } else {
1457                 if (_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
1458                         *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1459                         if (*psta == NULL) {
1460
1461                                 /* for AP multicast issue , modify by yiwei */
1462                                 static u32 send_issue_deauth_time = 0;
1463
1464                                 /* RTW_INFO("After send deauth , %u ms has elapsed.\n", rtw_get_passing_time_ms(send_issue_deauth_time)); */
1465
1466                                 if (rtw_get_passing_time_ms(send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) {
1467                                         send_issue_deauth_time = rtw_get_current_time();
1468
1469                                         RTW_INFO("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1470
1471                                         issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1472                                 }
1473                         }
1474                 }
1475
1476                 ret = _FAIL;
1477 #ifdef DBG_RX_DROP_FRAME
1478                 RTW_INFO("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
1479 #endif
1480         }
1481
1482 exit:
1483
1484         _func_exit_;
1485
1486         return ret;
1487
1488 }
1489
1490 sint sta2ap_data_frame(
1491         _adapter *adapter,
1492         union recv_frame *precv_frame,
1493         struct sta_info **psta);
1494 sint sta2ap_data_frame(
1495         _adapter *adapter,
1496         union recv_frame *precv_frame,
1497         struct sta_info **psta)
1498 {
1499         u8 *ptr = precv_frame->u.hdr.rx_data;
1500         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1501         struct  sta_priv                *pstapriv = &adapter->stapriv;
1502         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
1503         unsigned char *mybssid  = get_bssid(pmlmepriv);
1504         sint ret = _SUCCESS;
1505
1506         _func_enter_;
1507
1508         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1509                 /* For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
1510                 if (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1511                         ret = _FAIL;
1512                         goto exit;
1513                 }
1514
1515                 *psta = rtw_get_stainfo(pstapriv, pattrib->src);
1516                 if (*psta == NULL) {
1517 #ifdef CONFIG_DFS_MASTER
1518                         struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
1519
1520                         /* prevent RX tasklet blocks cmd_thread */
1521                         if (rfctl->radar_detected == 1)
1522                                 goto bypass_deauth7;
1523 #endif
1524
1525                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under AP_MODE; drop pkt\n"));
1526                         RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1527
1528                         issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1529
1530 #ifdef CONFIG_DFS_MASTER
1531 bypass_deauth7:
1532 #endif
1533                         ret = RTW_RX_HANDLED;
1534                         goto exit;
1535                 }
1536
1537                 process_pwrbit_data(adapter, precv_frame);
1538
1539                 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE)
1540                         process_wmmps_data(adapter, precv_frame);
1541
1542                 if (GetFrameSubType(ptr) & BIT(6)) {
1543                         /* No data, will not indicate to upper layer, temporily count it here */
1544                         count_rx_stats(adapter, precv_frame, *psta);
1545                         ret = RTW_RX_HANDLED;
1546                         goto exit;
1547                 }
1548         } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1549                    (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
1550                 /* RTW_INFO("%s ,in WIFI_MP_STATE\n",__func__); */
1551                 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1552                 _rtw_memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
1553                 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1554                 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1555                 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1556                 /*  */
1557                 if (adapter->mppriv.bRTWSmbCfg == _FALSE)
1558                         _rtw_memcpy(pattrib->bssid,  mybssid, ETH_ALEN);
1559
1560                 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1561                 if (*psta == NULL) {
1562                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n"));
1563 #ifdef DBG_RX_DROP_FRAME
1564                         RTW_INFO("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __FUNCTION__);
1565 #endif
1566                         ret = _FAIL;
1567                         goto exit;
1568                 }
1569
1570         } else {
1571                 u8 *myhwaddr = adapter_mac_addr(adapter);
1572                 if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1573                         ret = RTW_RX_HANDLED;
1574                         goto exit;
1575                 }
1576                 RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1577                 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1578                 ret = RTW_RX_HANDLED;
1579                 goto exit;
1580         }
1581
1582 exit:
1583
1584         _func_exit_;
1585
1586         return ret;
1587
1588 }
1589
1590 sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame);
1591 sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame)
1592 {
1593         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1594         struct sta_priv *pstapriv = &padapter->stapriv;
1595         u8 *pframe = precv_frame->u.hdr.rx_data;
1596         struct sta_info *psta = NULL;
1597         /* uint len = precv_frame->u.hdr.len; */
1598
1599         /* RTW_INFO("+validate_recv_ctrl_frame\n"); */
1600
1601         if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1602                 return _FAIL;
1603
1604         /* receive the frames that ra(a1) is my address */
1605         if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN))
1606                 return _FAIL;
1607
1608         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1609         if (psta == NULL)
1610                 return _FAIL;
1611
1612         /* for rx pkt statistics */
1613         psta->sta_stats.rx_ctrl_pkts++;
1614
1615         /* only handle ps-poll */
1616         if (GetFrameSubType(pframe) == WIFI_PSPOLL) {
1617 #ifdef CONFIG_AP_MODE
1618                 u16 aid;
1619                 u8 wmmps_ac = 0;
1620
1621                 aid = GetAid(pframe);
1622                 if (psta->aid != aid)
1623                         return _FAIL;
1624
1625                 switch (pattrib->priority) {
1626                 case 1:
1627                 case 2:
1628                         wmmps_ac = psta->uapsd_bk & BIT(0);
1629                         break;
1630                 case 4:
1631                 case 5:
1632                         wmmps_ac = psta->uapsd_vi & BIT(0);
1633                         break;
1634                 case 6:
1635                 case 7:
1636                         wmmps_ac = psta->uapsd_vo & BIT(0);
1637                         break;
1638                 case 0:
1639                 case 3:
1640                 default:
1641                         wmmps_ac = psta->uapsd_be & BIT(0);
1642                         break;
1643                 }
1644
1645                 if (wmmps_ac)
1646                         return _FAIL;
1647
1648                 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1649                         RTW_INFO("%s alive check-rx ps-poll\n", __func__);
1650                         psta->expire_to = pstapriv->expire_to;
1651                         psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1652                 }
1653
1654                 if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) {
1655                         _irqL irqL;
1656                         _list   *xmitframe_plist, *xmitframe_phead;
1657                         struct xmit_frame *pxmitframe = NULL;
1658                         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1659
1660                         /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
1661                         _enter_critical_bh(&pxmitpriv->lock, &irqL);
1662
1663                         xmitframe_phead = get_list_head(&psta->sleep_q);
1664                         xmitframe_plist = get_next(xmitframe_phead);
1665
1666                         if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
1667                                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1668
1669                                 xmitframe_plist = get_next(xmitframe_plist);
1670
1671                                 rtw_list_delete(&pxmitframe->list);
1672
1673                                 psta->sleepq_len--;
1674
1675                                 if (psta->sleepq_len > 0)
1676                                         pxmitframe->attrib.mdata = 1;
1677                                 else
1678                                         pxmitframe->attrib.mdata = 0;
1679
1680                                 pxmitframe->attrib.triggered = 1;
1681
1682                                 /* RTW_INFO("handling ps-poll, q_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1683
1684 #if 0
1685                                 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
1686                                 if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
1687                                         rtw_os_xmit_complete(padapter, pxmitframe);
1688                                 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
1689 #endif
1690                                 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1691
1692                                 if (psta->sleepq_len == 0) {
1693                                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
1694
1695                                         /* RTW_INFO("after handling ps-poll, tim=%x\n", pstapriv->tim_bitmap); */
1696
1697                                         /* upate BCN for TIM IE */
1698                                         /* update_BCNTIM(padapter);              */
1699                                         update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
1700                                 }
1701
1702                                 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
1703                                 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1704
1705                         } else {
1706                                 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
1707                                 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1708
1709                                 /* RTW_INFO("no buffered packets to xmit\n"); */
1710                                 if (pstapriv->tim_bitmap & BIT(psta->aid)) {
1711                                         if (psta->sleepq_len == 0) {
1712                                                 RTW_INFO("no buffered packets to xmit\n");
1713
1714                                                 /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1715                                                 issue_nulldata_in_interrupt(padapter, psta->hwaddr, 0);
1716                                         } else {
1717                                                 RTW_INFO("error!psta->sleepq_len=%d\n", psta->sleepq_len);
1718                                                 psta->sleepq_len = 0;
1719                                         }
1720
1721                                         pstapriv->tim_bitmap &= ~BIT(psta->aid);
1722
1723                                         /* upate BCN for TIM IE */
1724                                         /* update_BCNTIM(padapter); */
1725                                         update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
1726                                 }
1727                         }
1728                 }
1729 #endif /* CONFIG_AP_MODE */
1730         } else if (GetFrameSubType(pframe) == WIFI_NDPA) {
1731 #ifdef CONFIG_BEAMFORMING
1732                 beamforming_get_ndpa_frame(padapter, precv_frame);
1733 #endif/*CONFIG_BEAMFORMING*/
1734         }
1735
1736         return _FAIL;
1737
1738 }
1739
1740 union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame);
1741 sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame);
1742 sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame)
1743 {
1744         /* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */
1745
1746         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n"));
1747
1748 #if 0
1749         if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1750 #ifdef CONFIG_NATIVEAP_MLME
1751                 mgt_dispatcher(padapter, precv_frame);
1752 #else
1753                 rtw_hostapd_mlme_rx(padapter, precv_frame);
1754 #endif
1755         } else
1756                 mgt_dispatcher(padapter, precv_frame);
1757 #endif
1758
1759         precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1760         if (precv_frame == NULL) {
1761                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("%s: fragment packet\n", __FUNCTION__));
1762                 return _SUCCESS;
1763         }
1764
1765         {
1766                 /* for rx pkt statistics */
1767                 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data));
1768                 if (psta) {
1769                         psta->sta_stats.rx_mgnt_pkts++;
1770                         if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON)
1771                                 psta->sta_stats.rx_beacon_pkts++;
1772                         else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ)
1773                                 psta->sta_stats.rx_probereq_pkts++;
1774                         else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
1775                                 if (_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN) == _TRUE)
1776                                         psta->sta_stats.rx_probersp_pkts++;
1777                                 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))
1778                                         || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
1779                                         psta->sta_stats.rx_probersp_bm_pkts++;
1780                                 else
1781                                         psta->sta_stats.rx_probersp_uo_pkts++;
1782                         }
1783                 }
1784         }
1785
1786 #ifdef CONFIG_INTEL_PROXIM
1787         if (padapter->proximity.proxim_on == _TRUE) {
1788                 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1789                 struct recv_stat *prxstat = (struct recv_stat *)  precv_frame->u.hdr.rx_head ;
1790                 u8 *pda, *psa, *pbssid, *ptr;
1791                 ptr = precv_frame->u.hdr.rx_data;
1792                 pda = get_da(ptr);
1793                 psa = get_sa(ptr);
1794                 pbssid = get_hdr_bssid(ptr);
1795
1796
1797                 _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
1798                 _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
1799
1800                 _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1801
1802                 switch (pattrib->to_fr_ds) {
1803                 case 0:
1804                         _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
1805                         _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
1806                         break;
1807
1808                 case 1:
1809                         _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
1810                         _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
1811                         break;
1812
1813                 case 2:
1814                         _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
1815                         _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
1816                         break;
1817
1818                 case 3:
1819                         _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1820                         _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1821                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n"));
1822                         break;
1823
1824                 default:
1825                         break;
1826
1827                 }
1828                 pattrib->priority = 0;
1829                 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24;
1830
1831                 padapter->proximity.proxim_rx(padapter, precv_frame);
1832         }
1833 #endif
1834         mgt_dispatcher(padapter, precv_frame);
1835
1836         return _SUCCESS;
1837
1838 }
1839
1840 sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame);
1841 sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame)
1842 {
1843         u8 bretry;
1844         u8 *psa, *pda, *pbssid;
1845         struct sta_info *psta = NULL;
1846         u8 *ptr = precv_frame->u.hdr.rx_data;
1847         struct rx_pkt_attrib    *pattrib = &precv_frame->u.hdr.attrib;
1848         struct sta_priv *pstapriv = &adapter->stapriv;
1849         struct security_priv    *psecuritypriv = &adapter->securitypriv;
1850         sint ret = _SUCCESS;
1851
1852         _func_enter_;
1853
1854         bretry = GetRetry(ptr);
1855         pda = get_da(ptr);
1856         psa = get_sa(ptr);
1857         pbssid = get_hdr_bssid(ptr);
1858
1859         if (pbssid == NULL) {
1860 #ifdef DBG_RX_DROP_FRAME
1861                 RTW_INFO("DBG_RX_DROP_FRAME %s pbssid == NULL\n", __func__);
1862 #endif
1863                 ret = _FAIL;
1864                 goto exit;
1865         }
1866
1867         _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
1868         _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
1869
1870         _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1871
1872         switch (pattrib->to_fr_ds) {
1873         case 0:
1874                 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
1875                 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
1876                 ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1877                 break;
1878
1879         case 1:
1880                 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
1881                 _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
1882                 ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1883                 break;
1884
1885         case 2:
1886                 _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
1887                 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
1888                 ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1889                 break;
1890
1891         case 3:
1892                 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1893                 _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1894                 ret = _FAIL;
1895                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n"));
1896                 break;
1897
1898         default:
1899                 ret = _FAIL;
1900                 break;
1901
1902         }
1903
1904         if (ret == _FAIL) {
1905 #ifdef DBG_RX_DROP_FRAME
1906                 RTW_INFO("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __FUNCTION__, pattrib->to_fr_ds, ret);
1907 #endif
1908                 goto exit;
1909         } else if (ret == RTW_RX_HANDLED)
1910                 goto exit;
1911
1912
1913         if (psta == NULL) {
1914                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" after to_fr_ds_chk; psta==NULL\n"));
1915 #ifdef DBG_RX_DROP_FRAME
1916                 RTW_INFO("DBG_RX_DROP_FRAME %s psta == NULL\n", __func__);
1917 #endif
1918                 ret = _FAIL;
1919                 goto exit;
1920         }
1921
1922         /* psta->rssi = prxcmd->rssi; */
1923         /* psta->signal_quality= prxcmd->sq; */
1924         precv_frame->u.hdr.psta = psta;
1925
1926
1927         pattrib->amsdu = 0;
1928         pattrib->ack_policy = 0;
1929         /* parsing QC field */
1930         if (pattrib->qos == 1) {
1931                 pattrib->priority = GetPriority((ptr + 24));
1932                 pattrib->ack_policy = GetAckpolicy((ptr + 24));
1933                 pattrib->amsdu = GetAMsdu((ptr + 24));
1934                 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
1935
1936                 if (pattrib->priority != 0 && pattrib->priority != 3)
1937                         adapter->recvpriv.bIsAnyNonBEPkts = _TRUE;
1938                 else
1939                         adapter->recvpriv.bIsAnyNonBEPkts = _FALSE;
1940         } else {
1941                 pattrib->priority = 0;
1942                 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24;
1943         }
1944
1945
1946         if (pattrib->order) /* HT-CTRL 11n */
1947                 pattrib->hdrlen += 4;
1948
1949         precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1950
1951         /* decache, drop duplicate recv packets */
1952         if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) {
1953                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decache : drop pkt\n"));
1954 #ifdef DBG_RX_DROP_FRAME
1955                 RTW_INFO("DBG_RX_DROP_FRAME %s recv_decache return _FAIL\n", __func__);
1956 #endif
1957                 ret = _FAIL;
1958                 goto exit;
1959         }
1960
1961         if (pattrib->privacy) {
1962
1963                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("validate_recv_data_frame:pattrib->privacy=%x\n", pattrib->privacy));
1964                 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)));
1965
1966 #ifdef CONFIG_TDLS
1967                 if ((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy == _AES_))
1968                         pattrib->encrypt = psta->dot118021XPrivacy;
1969                 else
1970 #endif /* CONFIG_TDLS */
1971                         GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
1972
1973                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt=%d\n", pattrib->encrypt));
1974
1975                 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1976         } else {
1977                 pattrib->encrypt = 0;
1978                 pattrib->iv_len = pattrib->icv_len = 0;
1979         }
1980
1981 exit:
1982
1983         _func_exit_;
1984
1985         return ret;
1986 }
1987
1988 #ifdef CONFIG_IEEE80211W
1989 static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_frame)
1990 {
1991         struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1992         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1993         u8 *ptr = precv_frame->u.hdr.rx_data;
1994         struct sta_info *psta;
1995         struct sta_priv         *pstapriv = &adapter->stapriv;
1996         u8 type;
1997         u8 subtype;
1998
1999         type =  GetFrameType(ptr);
2000         subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */
2001
2002         if (adapter->securitypriv.binstallBIPkey == _TRUE) {
2003                 /* unicast management frame decrypt */
2004                 if (pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) &&
2005                     (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION)) {
2006                         u8 *ppp, *mgmt_DATA;
2007                         u32 data_len = 0;
2008                         ppp = GetAddr2Ptr(ptr);
2009
2010                         pattrib->bdecrypted = 0;
2011                         pattrib->encrypt = _AES_;
2012                         pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
2013                         /* set iv and icv length */
2014                         SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
2015                         _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2016                         _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
2017                         /* actual management data frame body */
2018                         data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
2019                         mgmt_DATA = rtw_zmalloc(data_len);
2020                         if (mgmt_DATA == NULL) {
2021                                 RTW_INFO("%s mgmt allocate fail  !!!!!!!!!\n", __FUNCTION__);
2022                                 goto validate_80211w_fail;
2023                         }
2024 #if 0
2025                         /* dump the packet content before decrypt */
2026                         {
2027                                 int pp;
2028                                 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
2029                                 for (pp = 0; pp < pattrib->pkt_len; pp++)
2030                                         printk(" %02x ", ptr[pp]);
2031                                 printk("\n");
2032                         }
2033 #endif
2034
2035                         precv_frame = decryptor(adapter, precv_frame);
2036                         /* save actual management data frame body */
2037                         _rtw_memcpy(mgmt_DATA, ptr + pattrib->hdrlen + pattrib->iv_len, data_len);
2038                         /* overwrite the iv field */
2039                         _rtw_memcpy(ptr + pattrib->hdrlen, mgmt_DATA, data_len);
2040                         /* remove the iv and icv length */
2041                         pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len;
2042                         rtw_mfree(mgmt_DATA, data_len);
2043 #if 0
2044                         /* print packet content after decryption */
2045                         {
2046                                 int pp;
2047                                 printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len);
2048                                 for (pp = 0; pp < pattrib->pkt_len; pp++)
2049                                         printk(" %02x ", ptr[pp]);
2050                                 printk("\n");
2051                         }
2052 #endif
2053                         if (!precv_frame) {
2054                                 RTW_INFO("%s mgmt descrypt fail  !!!!!!!!!\n", __FUNCTION__);
2055                                 goto validate_80211w_fail;
2056                         }
2057                 } else if (IS_MCAST(GetAddr1Ptr(ptr)) &&
2058                         (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)) {
2059                         sint BIP_ret = _SUCCESS;
2060                         /* verify BIP MME IE of broadcast/multicast de-auth/disassoc packet */
2061                         BIP_ret = rtw_BIP_verify(adapter, (u8 *)precv_frame);
2062                         if (BIP_ret == _FAIL) {
2063                                 /* RTW_INFO("802.11w BIP verify fail\n"); */
2064                                 goto validate_80211w_fail;
2065                         } else if (BIP_ret == RTW_RX_HANDLED) {
2066                                 RTW_INFO("802.11w recv none protected packet\n");
2067                                 /* drop pkt, don't issue sa query request */
2068                                 /* issue_action_SA_Query(adapter, NULL, 0, 0, 0); */
2069                                 goto validate_80211w_fail;
2070                         }
2071                 } /* 802.11w protect */
2072                 else {
2073                         psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(ptr));
2074
2075                         if (subtype == WIFI_ACTION && psta && psta->bpairwise_key_installed == _TRUE) {
2076                                 /* according 802.11-2012 standard, these five types are not robust types */
2077                                 if (ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC          &&
2078                                     ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT              &&
2079                                     ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM &&
2080                                     ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED  &&
2081                                     ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P) {
2082                                         RTW_INFO("action frame category=%d should robust\n", ptr[WLAN_HDR_A3_LEN]);
2083                                         goto validate_80211w_fail;
2084                                 }
2085                         } else if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
2086                                 unsigned short  reason;
2087                                 reason = le16_to_cpu(*(unsigned short *)(ptr + WLAN_HDR_A3_LEN));
2088                                 RTW_INFO("802.11w recv none protected packet, reason=%d\n", reason);
2089                                 if (reason == 6 || reason == 7) {
2090                                         /* issue sa query request */
2091                                         issue_action_SA_Query(adapter, NULL, 0, 0, IEEE80211W_RIGHT_KEY);
2092                                 }
2093                                 goto validate_80211w_fail;
2094                         }
2095                 }
2096         }
2097         return _SUCCESS;
2098
2099 validate_80211w_fail:
2100         return _FAIL;
2101
2102 }
2103 #endif /* CONFIG_IEEE80211W */
2104
2105 static inline void dump_rx_packet(u8 *ptr)
2106 {
2107         int i;
2108
2109         RTW_INFO("#############################\n");
2110         for (i = 0; i < 64; i = i + 8)
2111                 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
2112                         *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
2113         RTW_INFO("#############################\n");
2114 }
2115
2116 sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame);
2117 sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
2118 {
2119         /* shall check frame subtype, to / from ds, da, bssid */
2120
2121         /* then call check if rx seq/frag. duplicated. */
2122
2123         u8 type;
2124         u8 subtype;
2125         sint retval = _SUCCESS;
2126
2127         struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2128
2129         u8 *ptr = precv_frame->u.hdr.rx_data;
2130         u8  ver = (unsigned char)(*ptr) & 0x3 ;
2131 #ifdef CONFIG_FIND_BEST_CHANNEL
2132         struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2133 #endif
2134
2135 #ifdef CONFIG_TDLS
2136         struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
2137 #endif /* CONFIG_TDLS */
2138 #ifdef CONFIG_WAPI_SUPPORT
2139         PRT_WAPI_T      pWapiInfo = &adapter->wapiInfo;
2140         struct recv_frame_hdr *phdr = &precv_frame->u.hdr;
2141         u8 wai_pkt = 0;
2142         u16 sc;
2143         u8      external_len = 0;
2144 #endif
2145
2146         _func_enter_;
2147
2148 #ifdef CONFIG_FIND_BEST_CHANNEL
2149         if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
2150                 int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter));
2151                 if (ch_set_idx >= 0)
2152                         pmlmeext->channel_set[ch_set_idx].rx_count++;
2153         }
2154 #endif
2155
2156 #ifdef CONFIG_TDLS
2157         if (ptdlsinfo->ch_sensing == 1 && ptdlsinfo->cur_channel != 0)
2158                 ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel - 1]++;
2159 #endif /* CONFIG_TDLS */
2160
2161 #ifdef RTK_DMP_PLATFORM
2162         if (0) {
2163                 RTW_INFO("++\n");
2164                 {
2165                         int i;
2166                         for (i = 0; i < 64; i = i + 8)
2167                                 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr + i),
2168                                         *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
2169
2170                 }
2171                 RTW_INFO("--\n");
2172         }
2173 #endif /* RTK_DMP_PLATFORM */
2174
2175         /* add version chk */
2176         if (ver != 0) {
2177                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! (ver!=0)\n"));
2178                 retval = _FAIL;
2179                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err);
2180                 goto exit;
2181         }
2182
2183         type =  GetFrameType(ptr);
2184         subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */
2185
2186         pattrib->to_fr_ds = get_tofr_ds(ptr);
2187
2188         pattrib->frag_num = GetFragNum(ptr);
2189         pattrib->seq_num = GetSequence(ptr);
2190
2191         pattrib->pw_save = GetPwrMgt(ptr);
2192         pattrib->mfrag = GetMFrag(ptr);
2193         pattrib->mdata = GetMData(ptr);
2194         pattrib->privacy = GetPrivacy(ptr);
2195         pattrib->order = GetOrder(ptr);
2196 #ifdef CONFIG_WAPI_SUPPORT
2197         sc = (pattrib->seq_num << 4) | pattrib->frag_num;
2198 #endif
2199
2200 #if 1 /* Dump rx packets */
2201         {
2202                 u8 bDumpRxPkt = 0;
2203
2204                 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
2205                 if (bDumpRxPkt == 1) /* dump all rx packets */
2206                         dump_rx_packet(ptr);
2207                 else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE))
2208                         dump_rx_packet(ptr);
2209                 else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE))
2210                         dump_rx_packet(ptr);
2211         }
2212 #endif
2213         switch (type) {
2214         case WIFI_MGT_TYPE: /* mgnt */
2215                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt);
2216 #ifdef CONFIG_IEEE80211W
2217                 if (validate_80211w_mgmt(adapter, precv_frame) == _FAIL) {
2218                         retval = _FAIL;
2219                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err_80211w);
2220                         break;
2221                 }
2222 #endif /* CONFIG_IEEE80211W */
2223
2224                 retval = validate_recv_mgnt_frame(adapter, precv_frame);
2225                 if (retval == _FAIL) {
2226                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_mgnt_frame fail\n"));
2227                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err);
2228                 }
2229                 retval = _FAIL; /* only data frame return _SUCCESS */
2230                 break;
2231         case WIFI_CTRL_TYPE: /* ctrl */
2232                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl);
2233                 retval = validate_recv_ctrl_frame(adapter, precv_frame);
2234                 if (retval == _FAIL) {
2235                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_ctrl_frame fail\n"));
2236                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err);
2237                 }
2238                 retval = _FAIL; /* only data frame return _SUCCESS */
2239                 break;
2240         case WIFI_DATA_TYPE: /* data */
2241                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data);
2242 #ifdef CONFIG_WAPI_SUPPORT
2243                 if (pattrib->qos)
2244                         external_len = 2;
2245                 else
2246                         external_len = 0;
2247
2248                 wai_pkt = rtw_wapi_is_wai_packet(adapter, ptr);
2249
2250                 phdr->bIsWaiPacket = wai_pkt;
2251
2252                 if (wai_pkt != 0) {
2253                         if (sc != adapter->wapiInfo.wapiSeqnumAndFragNum)
2254                                 adapter->wapiInfo.wapiSeqnumAndFragNum = sc;
2255                         else {
2256                                 retval = _FAIL;
2257                                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_seq_err);
2258                                 break;
2259                         }
2260                 } else {
2261
2262                         if (rtw_wapi_drop_for_key_absent(adapter, GetAddr2Ptr(ptr))) {
2263                                 retval = _FAIL;
2264                                 WAPI_TRACE(WAPI_RX, "drop for key absent for rx\n");
2265                                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_key_err);
2266                                 break;
2267                         }
2268                 }
2269
2270 #endif
2271
2272                 pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
2273                 retval = validate_recv_data_frame(adapter, precv_frame);
2274                 if (retval == _FAIL) {
2275                         struct recv_priv *precvpriv = &adapter->recvpriv;
2276                         /* RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail\n")); */
2277                         precvpriv->rx_drop++;
2278                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err);
2279                 } else if (retval == _SUCCESS) {
2280 #ifdef DBG_RX_DUMP_EAP
2281                         u8 bDumpRxPkt;
2282                         u16 eth_type;
2283
2284                         /* dump eapol */
2285                         rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
2286                         /* get ether_type */
2287                         _rtw_memcpy(&eth_type, ptr + pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE, 2);
2288                         eth_type = ntohs((unsigned short) eth_type);
2289                         if ((bDumpRxPkt == 4) && (eth_type == 0x888e))
2290                                 dump_rx_packet(ptr);
2291 #endif
2292                 } else
2293                         DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled);
2294                 break;
2295         default:
2296                 DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown);
2297                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! type=0x%x\n", type));
2298 #ifdef DBG_RX_DROP_FRAME
2299                 RTW_INFO("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type=0x%x\n", type);
2300 #endif
2301                 retval = _FAIL;
2302                 break;
2303         }
2304
2305 exit:
2306
2307         _func_exit_;
2308
2309         return retval;
2310 }
2311
2312
2313 /* remove the wlanhdr and add the eth_hdr */
2314 #if 1
2315
2316 sint wlanhdr_to_ethhdr(union recv_frame *precvframe);
2317 sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
2318 {
2319         sint    rmv_len;
2320         u16     eth_type, len;
2321         u8      bsnaphdr;
2322         u8      *psnap_type;
2323         struct ieee80211_snap_hdr       *psnap;
2324
2325         sint ret = _SUCCESS;
2326         _adapter                        *adapter = precvframe->u.hdr.adapter;
2327         struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
2328
2329         u8      *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
2330         struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
2331
2332         _func_enter_;
2333
2334         if (pattrib->encrypt)
2335                 recvframe_pull_tail(precvframe, pattrib->icv_len);
2336
2337         psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
2338         psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
2339         /* convert hdr + possible LLC headers into Ethernet header */
2340         /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
2341         if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
2342              (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) &&
2343              (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) ||
2344             /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
2345             _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
2346                 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2347                 bsnaphdr = _TRUE;
2348         } else {
2349                 /* Leave Ethernet header part of hdr and full payload */
2350                 bsnaphdr = _FALSE;
2351         }
2352
2353         rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
2354         len = precvframe->u.hdr.len - rmv_len;
2355
2356         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n===pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n\n", pattrib->hdrlen,  pattrib->iv_len));
2357
2358         _rtw_memcpy(&eth_type, ptr + rmv_len, 2);
2359         eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
2360         pattrib->eth_type = eth_type;
2361
2362 #ifdef CONFIG_AUTO_AP_MODE
2363         if (0x8899 == pattrib->eth_type) {
2364                 struct sta_info *psta = precvframe->u.hdr.psta;
2365
2366                 RTW_INFO("wlan rx: got eth_type=0x%x\n", pattrib->eth_type);
2367
2368                 if (psta && psta->isrc && psta->pid > 0) {
2369                         u16 rx_pid;
2370
2371                         rx_pid = *(u16 *)(ptr + rmv_len + 2);
2372
2373                         RTW_INFO("wlan rx(pid=0x%x): sta("MAC_FMT") pid=0x%x\n",
2374                                  rx_pid, MAC_ARG(psta->hwaddr), psta->pid);
2375
2376                         if (rx_pid == psta->pid) {
2377                                 int i;
2378                                 u16 len = *(u16 *)(ptr + rmv_len + 4);
2379                                 /* u16 ctrl_type = *(u16*)(ptr+rmv_len+6); */
2380
2381                                 /* RTW_INFO("RC: len=0x%x, ctrl_type=0x%x\n", len, ctrl_type);  */
2382                                 RTW_INFO("RC: len=0x%x\n", len);
2383
2384                                 for (i = 0; i < len; i++)
2385                                         RTW_INFO("0x%x\n", *(ptr + rmv_len + 6 + i));
2386                                 /* RTW_INFO("0x%x\n", *(ptr+rmv_len+8+i)); */
2387
2388                                 RTW_INFO("RC-end\n");
2389                         }
2390                 }
2391         }
2392 #endif /* CONFIG_AUTO_AP_MODE */
2393
2394         if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)) {
2395                 ptr += rmv_len ;
2396                 *ptr = 0x87;
2397                 *(ptr + 1) = 0x12;
2398
2399                 eth_type = 0x8712;
2400                 /* append rx status for mp test packets */
2401                 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
2402                 if (!ptr) {
2403                         ret = _FAIL;
2404                         goto exiting;
2405                 }
2406                 _rtw_memcpy(ptr, get_rxmem(precvframe), 24);
2407                 ptr += 24;
2408         } else {
2409                 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
2410                 if (!ptr) {
2411                         ret = _FAIL;
2412                         goto exiting;
2413                 }
2414         }
2415
2416         if (ptr) {
2417                 _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2418                 _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
2419
2420                 if (!bsnaphdr) {
2421                         len = htons(len);
2422                         _rtw_memcpy(ptr + 12, &len, 2);
2423                 }
2424         }
2425
2426 exiting:
2427         _func_exit_;
2428         return ret;
2429
2430 }
2431
2432 #else
2433
2434 sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
2435 {
2436         sint rmv_len;
2437         u16 eth_type;
2438         u8      bsnaphdr;
2439         u8      *psnap_type;
2440         struct ieee80211_snap_hdr       *psnap;
2441
2442         sint ret = _SUCCESS;
2443         _adapter        *adapter = precvframe->u.hdr.adapter;
2444         struct  mlme_priv       *pmlmepriv = &adapter->mlmepriv;
2445
2446         u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
2447         struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
2448         struct _vlan *pvlan = NULL;
2449
2450         _func_enter_;
2451
2452         psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
2453         psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
2454         if (psnap->dsap == 0xaa && psnap->ssap == 0xaa && psnap->ctrl == 0x03) {
2455                 if (_rtw_memcmp(psnap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN))
2456                         bsnaphdr = _TRUE; /* wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042;     */
2457                 else if (_rtw_memcmp(psnap->oui, SNAP_HDR_APPLETALK_DDP, WLAN_IEEE_OUI_LEN) &&
2458                         _rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_DDP, 2))
2459                         bsnaphdr = _TRUE;       /* wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK; */
2460                 else if (_rtw_memcmp(psnap->oui, oui_8021h, WLAN_IEEE_OUI_LEN))
2461                         bsnaphdr = _TRUE;       /* wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL; */
2462                 else {
2463                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("drop pkt due to invalid frame format!\n"));
2464                         ret = _FAIL;
2465                         goto exit;
2466                 }
2467
2468         } else
2469                 bsnaphdr = _FALSE; /* wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS; */
2470
2471         rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
2472         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("===pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n", pattrib->hdrlen,  pattrib->iv_len));
2473
2474         if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) {
2475                 ptr += rmv_len ;
2476                 *ptr = 0x87;
2477                 *(ptr + 1) = 0x12;
2478
2479                 /* back to original pointer */
2480                 ptr -= rmv_len;
2481         }
2482
2483         ptr += rmv_len ;
2484
2485         _rtw_memcpy(&eth_type, ptr, 2);
2486         eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
2487         ptr += 2;
2488
2489         if (pattrib->encrypt)
2490                 recvframe_pull_tail(precvframe, pattrib->icv_len);
2491
2492         if (eth_type == 0x8100) { /* vlan */
2493                 pvlan = (struct _vlan *) ptr;
2494
2495                 /* eth_type = get_vlan_encap_proto(pvlan); */
2496                 /* eth_type = pvlan->h_vlan_encapsulated_proto; */ /* ? */
2497                 rmv_len += 4;
2498                 ptr += 4;
2499         }
2500
2501         if (eth_type == 0x0800) { /* ip */
2502                 /* struct iphdr*  piphdr = (struct iphdr*) ptr; */
2503                 /* __u8 tos = (unsigned char)(pattrib->priority & 0xff); */
2504
2505                 /* piphdr->tos = tos; */
2506
2507                 /* if (piphdr->protocol == 0x06) */
2508                 /* { */
2509                 /*      RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", precvframe->u.hdr.len)); */
2510                 /* } */
2511         } else if (eth_type == 0x8712) { /* append rx status for mp test packets */
2512                 /* ptr -= 16; */
2513                 /* _rtw_memcpy(ptr, get_rxmem(precvframe), 16); */
2514         } else {
2515 #ifdef PLATFORM_OS_XP
2516                 NDIS_PACKET_8021Q_INFO VlanPriInfo;
2517                 UINT32 UserPriority = precvframe->u.hdr.attrib.priority;
2518                 UINT32 VlanID = (pvlan != NULL ? get_vlan_id(pvlan) : 0);
2519
2520                 VlanPriInfo.Value =          /* Get current value. */
2521                         NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo);
2522
2523                 VlanPriInfo.TagHeader.UserPriority = UserPriority;
2524                 VlanPriInfo.TagHeader.VlanId =  VlanID ;
2525
2526                 VlanPriInfo.TagHeader.CanonicalFormatId = 0; /* Should be zero. */
2527                 VlanPriInfo.TagHeader.Reserved = 0; /* Should be zero. */
2528                 NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo) = VlanPriInfo.Value;
2529 #endif
2530         }
2531
2532         if (eth_type == 0x8712) { /* append rx status for mp test packets */
2533                 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
2534                 _rtw_memcpy(ptr, get_rxmem(precvframe), 24);
2535                 ptr += 24;
2536         } else
2537                 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2));
2538
2539         _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2540         _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
2541
2542         eth_type = htons((unsigned short)eth_type) ;
2543         _rtw_memcpy(ptr + 12, &eth_type, 2);
2544
2545 exit:
2546
2547         _func_exit_;
2548
2549         return ret;
2550 }
2551 #endif
2552
2553
2554 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2555 #ifdef PLATFORM_LINUX
2556 static void recvframe_expand_pkt(
2557         PADAPTER padapter,
2558         union recv_frame *prframe)
2559 {
2560         struct recv_frame_hdr *pfhdr;
2561         _pkt *ppkt;
2562         u8 shift_sz;
2563         u32 alloc_sz;
2564         u8 *ptr;
2565
2566
2567         pfhdr = &prframe->u.hdr;
2568
2569         /*      6 is for IP header 8 bytes alignment in QoS packet case. */
2570         if (pfhdr->attrib.qos)
2571                 shift_sz = 6;
2572         else
2573                 shift_sz = 0;
2574
2575         /* for first fragment packet, need to allocate */
2576         /* (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet */
2577         /*      8 is for skb->data 8 bytes alignment.
2578         *       alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); */
2579         alloc_sz = 1664; /* round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment */
2580
2581         /* 3 1. alloc new skb */
2582         /* prepare extra space for 4 bytes alignment */
2583         ppkt = rtw_skb_alloc(alloc_sz);
2584
2585         if (!ppkt)
2586                 return; /* no way to expand */
2587
2588         /* 3 2. Prepare new skb to replace & release old skb */
2589         /* force ppkt->data at 8-byte alignment address */
2590         skb_reserve(ppkt, 8 - ((SIZE_PTR)ppkt->data & 7));
2591         /* force ip_hdr at 8-byte alignment address according to shift_sz */
2592         skb_reserve(ppkt, shift_sz);
2593
2594         /* copy data to new pkt */
2595         ptr = skb_put(ppkt, pfhdr->len);
2596         if (ptr)
2597                 _rtw_memcpy(ptr, pfhdr->rx_data, pfhdr->len);
2598
2599         rtw_skb_free(pfhdr->pkt);
2600
2601         /* attach new pkt to recvframe */
2602         pfhdr->pkt = ppkt;
2603         pfhdr->rx_head = ppkt->head;
2604         pfhdr->rx_data = ppkt->data;
2605         pfhdr->rx_tail = skb_tail_pointer(ppkt);
2606         pfhdr->rx_end = skb_end_pointer(ppkt);
2607 }
2608 #else
2609 #warning "recvframe_expand_pkt not implement, defrag may crash system"
2610 #endif
2611 #endif
2612
2613 /* perform defrag */
2614 union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q);
2615 union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q)
2616 {
2617         _list   *plist, *phead;
2618         u8      *data, wlanhdr_offset;
2619         u8      curfragnum;
2620         struct recv_frame_hdr *pfhdr, *pnfhdr;
2621         union recv_frame *prframe, *pnextrframe;
2622         _queue  *pfree_recv_queue;
2623
2624         _func_enter_;
2625
2626         curfragnum = 0;
2627         pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
2628
2629         phead = get_list_head(defrag_q);
2630         plist = get_next(phead);
2631         prframe = LIST_CONTAINOR(plist, union recv_frame, u);
2632         pfhdr = &prframe->u.hdr;
2633         rtw_list_delete(&(prframe->u.list));
2634
2635         if (curfragnum != pfhdr->attrib.frag_num) {
2636                 /* the first fragment number must be 0 */
2637                 /* free the whole queue */
2638                 rtw_free_recvframe(prframe, pfree_recv_queue);
2639                 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2640
2641                 return NULL;
2642         }
2643
2644 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2645 #ifndef CONFIG_SDIO_RX_COPY
2646         recvframe_expand_pkt(adapter, prframe);
2647 #endif
2648 #endif
2649
2650         curfragnum++;
2651
2652         plist = get_list_head(defrag_q);
2653
2654         plist = get_next(plist);
2655
2656         data = get_recvframe_data(prframe);
2657
2658         while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
2659                 pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u);
2660                 pnfhdr = &pnextrframe->u.hdr;
2661
2662
2663                 /* check the fragment sequence  (2nd ~n fragment frame) */
2664
2665                 if (curfragnum != pnfhdr->attrib.frag_num) {
2666                         /* the fragment number must be increasing  (after decache) */
2667                         /* release the defrag_q & prframe */
2668                         rtw_free_recvframe(prframe, pfree_recv_queue);
2669                         rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2670                         return NULL;
2671                 }
2672
2673                 curfragnum++;
2674
2675                 /* copy the 2nd~n fragment frame's payload to the first fragment */
2676                 /* get the 2nd~last fragment frame's payload */
2677
2678                 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
2679
2680                 recvframe_pull(pnextrframe, wlanhdr_offset);
2681
2682                 /* append  to first fragment frame's tail (if privacy frame, pull the ICV) */
2683                 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
2684
2685                 /* memcpy */
2686                 _rtw_memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
2687
2688                 recvframe_put(prframe, pnfhdr->len);
2689
2690                 pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
2691                 plist = get_next(plist);
2692
2693         };
2694
2695         /* free the defrag_q queue and return the prframe */
2696         rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2697
2698         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Performance defrag!!!!!\n"));
2699
2700         _func_exit_;
2701
2702         return prframe;
2703 }
2704
2705 /* check if need to defrag, if needed queue the frame to defrag_q */
2706 union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame)
2707 {
2708         u8      ismfrag;
2709         u8      fragnum;
2710         u8      *psta_addr;
2711         struct recv_frame_hdr *pfhdr;
2712         struct sta_info *psta;
2713         struct sta_priv *pstapriv;
2714         _list *phead;
2715         union recv_frame *prtnframe = NULL;
2716         _queue *pfree_recv_queue, *pdefrag_q;
2717
2718         _func_enter_;
2719
2720         pstapriv = &padapter->stapriv;
2721
2722         pfhdr = &precv_frame->u.hdr;
2723
2724         pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2725
2726         /* need to define struct of wlan header frame ctrl */
2727         ismfrag = pfhdr->attrib.mfrag;
2728         fragnum = pfhdr->attrib.frag_num;
2729
2730         psta_addr = pfhdr->attrib.ta;
2731         psta = rtw_get_stainfo(pstapriv, psta_addr);
2732         if (psta == NULL) {
2733                 u8 type = GetFrameType(pfhdr->rx_data);
2734                 if (type != WIFI_DATA_TYPE) {
2735                         psta = rtw_get_bcmc_stainfo(padapter);
2736                         pdefrag_q = &psta->sta_recvpriv.defrag_q;
2737                 } else
2738                         pdefrag_q = NULL;
2739         } else
2740                 pdefrag_q = &psta->sta_recvpriv.defrag_q;
2741
2742         if ((ismfrag == 0) && (fragnum == 0)) {
2743                 prtnframe = precv_frame;/* isn't a fragment frame */
2744         }
2745
2746         if (ismfrag == 1) {
2747                 /* 0~(n-1) fragment frame */
2748                 /* enqueue to defraf_g */
2749                 if (pdefrag_q != NULL) {
2750                         if (fragnum == 0) {
2751                                 /* the first fragment */
2752                                 if (_rtw_queue_empty(pdefrag_q) == _FALSE) {
2753                                         /* free current defrag_q */
2754                                         rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
2755                                 }
2756                         }
2757
2758
2759                         /* Then enqueue the 0~(n-1) fragment into the defrag_q */
2760
2761                         /* _rtw_spinlock(&pdefrag_q->lock); */
2762                         phead = get_list_head(pdefrag_q);
2763                         rtw_list_insert_tail(&pfhdr->list, phead);
2764                         /* _rtw_spinunlock(&pdefrag_q->lock); */
2765
2766                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Enqueuq: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2767
2768                         prtnframe = NULL;
2769
2770                 } else {
2771                         /* can't find this ta's defrag_queue, so free this recv_frame */
2772                         rtw_free_recvframe(precv_frame, pfree_recv_queue);
2773                         prtnframe = NULL;
2774                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2775                 }
2776
2777         }
2778
2779         if ((ismfrag == 0) && (fragnum != 0)) {
2780                 /* the last fragment frame */
2781                 /* enqueue the last fragment */
2782                 if (pdefrag_q != NULL) {
2783                         /* _rtw_spinlock(&pdefrag_q->lock); */
2784                         phead = get_list_head(pdefrag_q);
2785                         rtw_list_insert_tail(&pfhdr->list, phead);
2786                         /* _rtw_spinunlock(&pdefrag_q->lock); */
2787
2788                         /* call recvframe_defrag to defrag */
2789                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("defrag: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2790                         precv_frame = recvframe_defrag(padapter, pdefrag_q);
2791                         prtnframe = precv_frame;
2792
2793                 } else {
2794                         /* can't find this ta's defrag_queue, so free this recv_frame */
2795                         rtw_free_recvframe(precv_frame, pfree_recv_queue);
2796                         prtnframe = NULL;
2797                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2798                 }
2799
2800         }
2801
2802
2803         if ((prtnframe != NULL) && (prtnframe->u.hdr.attrib.privacy)) {
2804                 /* after defrag we must check tkip mic code */
2805                 if (recvframe_chkmic(padapter,  prtnframe) == _FAIL) {
2806                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic(padapter,  prtnframe)==_FAIL\n"));
2807                         rtw_free_recvframe(prtnframe, pfree_recv_queue);
2808                         prtnframe = NULL;
2809                 }
2810         }
2811
2812         _func_exit_;
2813
2814         return prtnframe;
2815
2816 }
2817
2818 int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
2819 {
2820         int     a_len, padding_len;
2821         u16     nSubframe_Length;
2822         u8      nr_subframes, i;
2823         u8      *pdata;
2824         _pkt *sub_pkt, *subframes[MAX_SUBFRAME_COUNT];
2825         struct recv_priv *precvpriv = &padapter->recvpriv;
2826         _queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
2827         int     ret = _SUCCESS;
2828
2829         nr_subframes = 0;
2830
2831         recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
2832
2833         if (prframe->u.hdr.attrib.iv_len > 0)
2834                 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
2835
2836         a_len = prframe->u.hdr.len;
2837
2838         pdata = prframe->u.hdr.rx_data;
2839
2840         while (a_len > ETH_HLEN) {
2841
2842                 /* Offset 12 denote 2 mac address */
2843                 nSubframe_Length = RTW_GET_BE16(pdata + 12);
2844
2845                 if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
2846                         RTW_INFO("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
2847                         break;
2848                 }
2849
2850                 sub_pkt = rtw_os_alloc_msdu_pkt(prframe, nSubframe_Length, pdata);
2851                 if (sub_pkt == NULL) {
2852                         RTW_INFO("%s(): allocate sub packet fail !!!\n", __FUNCTION__);
2853                         break;
2854                 }
2855
2856                 /* move the data point to data content */
2857                 pdata += ETH_HLEN;
2858                 a_len -= ETH_HLEN;
2859
2860                 subframes[nr_subframes++] = sub_pkt;
2861
2862                 if (nr_subframes >= MAX_SUBFRAME_COUNT) {
2863                         RTW_INFO("ParseSubframe(): Too many Subframes! Packets dropped!\n");
2864                         break;
2865                 }
2866
2867                 pdata += nSubframe_Length;
2868                 a_len -= nSubframe_Length;
2869                 if (a_len != 0) {
2870                         padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1));
2871                         if (padding_len == 4)
2872                                 padding_len = 0;
2873
2874                         if (a_len < padding_len) {
2875                                 RTW_INFO("ParseSubframe(): a_len < padding_len !\n");
2876                                 break;
2877                         }
2878                         pdata += padding_len;
2879                         a_len -= padding_len;
2880                 }
2881         }
2882
2883         for (i = 0; i < nr_subframes; i++) {
2884                 sub_pkt = subframes[i];
2885
2886                 /* Indicat the packets to upper layer */
2887                 if (sub_pkt)
2888                         rtw_os_recv_indicate_pkt(padapter, sub_pkt, &prframe->u.hdr.attrib);
2889         }
2890
2891         prframe->u.hdr.len = 0;
2892         rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
2893
2894         return ret;
2895 }
2896
2897 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
2898 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
2899 {
2900         PADAPTER padapter = preorder_ctrl->padapter;
2901         struct dvobj_priv *psdpriv = padapter->dvobj;
2902         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
2903         u8      wsize = preorder_ctrl->wsize_b;
2904         u16     wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF; /* % 4096; */
2905
2906         /* Rx Reorder initialize condition. */
2907         if (preorder_ctrl->indicate_seq == 0xFFFF) {
2908                 preorder_ctrl->indicate_seq = seq_num;
2909 #ifdef DBG_RX_SEQ
2910                 RTW_INFO("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2911                          preorder_ctrl->indicate_seq, seq_num);
2912 #endif
2913
2914                 /* DbgPrint("check_indicate_seq, 1st->indicate_seq=%d\n", precvpriv->indicate_seq); */
2915         }
2916
2917         /* DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2918
2919         /* Drop out the packet which SeqNum is smaller than WinStart */
2920         if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) {
2921                 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */
2922                 /* DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2923
2924 #ifdef DBG_RX_DROP_FRAME
2925                 RTW_INFO("%s IndicateSeq: %d > NewSeq: %d\n", __FUNCTION__,
2926                          preorder_ctrl->indicate_seq, seq_num);
2927 #endif
2928
2929
2930                 return _FALSE;
2931         }
2932
2933         /*  */
2934         /* Sliding window manipulation. Conditions includes: */
2935         /* 1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
2936         /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */
2937         /*  */
2938         if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
2939                 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2940
2941 #ifdef DBG_RX_SEQ
2942                 RTW_INFO("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2943                          preorder_ctrl->indicate_seq, seq_num);
2944 #endif
2945         } else if (SN_LESS(wend, seq_num)) {
2946                 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */
2947                 /* DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2948
2949                 /* boundary situation, when seq_num cross 0xFFF */
2950                 if (seq_num >= (wsize - 1))
2951                         preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
2952                 else
2953                         preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
2954                 pdbgpriv->dbg_rx_ampdu_window_shift_cnt++;
2955 #ifdef DBG_RX_SEQ
2956                 RTW_INFO("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
2957                          preorder_ctrl->indicate_seq, seq_num);
2958 #endif
2959         }
2960
2961         /* DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */
2962
2963         return _TRUE;
2964 }
2965
2966 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe);
2967 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe)
2968 {
2969         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2970         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2971         _list   *phead, *plist;
2972         union recv_frame *pnextrframe;
2973         struct rx_pkt_attrib *pnextattrib;
2974
2975         /* DbgPrint("+enqueue_reorder_recvframe()\n"); */
2976
2977         /* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
2978         /* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
2979
2980
2981         phead = get_list_head(ppending_recvframe_queue);
2982         plist = get_next(phead);
2983
2984         while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
2985                 pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
2986                 pnextattrib = &pnextrframe->u.hdr.attrib;
2987
2988                 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
2989                         plist = get_next(plist);
2990                 else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
2991                         /* Duplicate entry is found!! Do not insert current entry. */
2992                         /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
2993
2994                         /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
2995
2996                         return _FALSE;
2997                 } else
2998                         break;
2999
3000                 /* DbgPrint("enqueue_reorder_recvframe():while\n"); */
3001
3002         }
3003
3004
3005         /* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3006         /* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3007
3008         rtw_list_delete(&(prframe->u.hdr.list));
3009
3010         rtw_list_insert_tail(&(prframe->u.hdr.list), plist);
3011
3012         /* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3013         /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3014
3015
3016         /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
3017         return _TRUE;
3018
3019 }
3020
3021 void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq);
3022 void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq)
3023 {
3024         if (current_seq < prev_seq)
3025                 pdbgpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq);
3026
3027         else
3028                 pdbgpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq);
3029 }
3030 int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced);
3031 int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
3032 {
3033         /* _irqL irql; */
3034         /* u8 bcancelled; */
3035         _list   *phead, *plist;
3036         union recv_frame *prframe;
3037         struct rx_pkt_attrib *pattrib;
3038         /* u8 index = 0; */
3039         int bPktInBuf = _FALSE;
3040         struct recv_priv *precvpriv = &padapter->recvpriv;
3041         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3042         struct dvobj_priv *psdpriv = padapter->dvobj;
3043         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
3044
3045         DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder);
3046
3047         /* DbgPrint("+recv_indicatepkts_in_order\n"); */
3048
3049         /* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3050         /* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3051
3052         phead = get_list_head(ppending_recvframe_queue);
3053         plist = get_next(phead);
3054
3055 #if 0
3056         /* Check if there is any other indication thread running. */
3057         if (pTS->RxIndicateState == RXTS_INDICATE_PROCESSING)
3058                 return;
3059 #endif
3060
3061         /* Handling some condition for forced indicate case. */
3062         if (bforced == _TRUE) {
3063                 pdbgpriv->dbg_rx_ampdu_forced_indicate_count++;
3064                 if (rtw_is_list_empty(phead)) {
3065                         /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3066                         /* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3067                         return _TRUE;
3068                 }
3069
3070                 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3071                 pattrib = &prframe->u.hdr.attrib;
3072
3073 #ifdef DBG_RX_SEQ
3074                 RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3075                          preorder_ctrl->indicate_seq, pattrib->seq_num);
3076 #endif
3077                 recv_indicatepkts_pkt_loss_cnt(pdbgpriv, preorder_ctrl->indicate_seq, pattrib->seq_num);
3078                 preorder_ctrl->indicate_seq = pattrib->seq_num;
3079
3080         }
3081
3082         /* Prepare indication list and indication. */
3083         /* Check if there is any packet need indicate. */
3084         while (!rtw_is_list_empty(phead)) {
3085
3086                 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3087                 pattrib = &prframe->u.hdr.attrib;
3088
3089                 if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
3090                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
3091                                 ("recv_indicatepkts_in_order: indicate=%d seq=%d amsdu=%d\n",
3092                                 preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu));
3093
3094 #if 0
3095                         /* This protect buffer from overflow. */
3096                         if (index >= REORDER_WIN_SIZE) {
3097                                 RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!!\n"));
3098                                 bPktInBuf = TRUE;
3099                                 break;
3100                         }
3101 #endif
3102
3103                         plist = get_next(plist);
3104                         rtw_list_delete(&(prframe->u.hdr.list));
3105
3106                         if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
3107                                 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3108 #ifdef DBG_RX_SEQ
3109                                 RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3110                                         preorder_ctrl->indicate_seq, pattrib->seq_num);
3111 #endif
3112                         }
3113
3114 #if 0
3115                         index++;
3116                         if (index == 1) {
3117                                 /* Cancel previous pending timer. */
3118                                 /* PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer); */
3119                                 if (bforced != _TRUE) {
3120                                         /* RTW_INFO("_cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);\n"); */
3121                                         _cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);
3122                                 }
3123                         }
3124 #endif
3125
3126                         /* Set this as a lock to make sure that only one thread is indicating packet. */
3127                         /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */
3128
3129                         /* Indicate packets */
3130                         /* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */
3131
3132
3133                         /* indicate this recv_frame */
3134                         /* DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num); */
3135                         if (!pattrib->amsdu) {
3136                                 /* RTW_INFO("recv_indicatepkts_in_order, amsdu!=1, indicate_seq=%d, seq_num=%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num); */
3137
3138                                 if (!RTW_CANNOT_RUN(padapter))
3139                                         rtw_recv_indicatepkt(padapter, prframe);/*indicate this recv_frame*/
3140
3141                         } else if (pattrib->amsdu == 1) {
3142                                 if (amsdu_to_msdu(padapter, prframe) != _SUCCESS)
3143                                         rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
3144                         } else {
3145                                 /* error condition; */
3146                         }
3147
3148
3149                         /* Update local variables. */
3150                         bPktInBuf = _FALSE;
3151
3152                 } else {
3153                         bPktInBuf = _TRUE;
3154                         break;
3155                 }
3156
3157                 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
3158
3159         }
3160
3161         /* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3162         /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3163
3164 #if 0
3165         /* Release the indication lock and set to new indication step. */
3166         if (bPktInBuf) {
3167                 /*  Set new pending timer. */
3168                 /* pTS->RxIndicateState = RXTS_INDICATE_REORDER; */
3169                 /* PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime); */
3170
3171                 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3172         } else {
3173                 /* pTS->RxIndicateState = RXTS_INDICATE_IDLE; */
3174         }
3175 #endif
3176         /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3177
3178         /* return _TRUE; */
3179         return bPktInBuf;
3180
3181 }
3182
3183 int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe);
3184 int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe)
3185 {
3186         _irqL irql;
3187         int retval = _SUCCESS;
3188         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3189         struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
3190         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3191         struct dvobj_priv *psdpriv = padapter->dvobj;
3192         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
3193
3194         DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder);
3195
3196         if (!pattrib->amsdu) {
3197                 /* s1. */
3198                 retval = wlanhdr_to_ethhdr(prframe);
3199                 if (retval != _SUCCESS) {
3200                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n"));
3201 #ifdef DBG_RX_DROP_FRAME
3202                         RTW_INFO("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __FUNCTION__);
3203 #endif
3204                         return retval;
3205                 }
3206
3207                 /* if ((pattrib->qos!=1) || pattrib->priority!=0 || IS_MCAST(pattrib->ra) */
3208                 /*      || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0)) */
3209                 if (pattrib->qos != 1) {
3210                         if (!RTW_CANNOT_RUN(padapter)) {
3211                                 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@  recv_indicatepkt_reorder -recv_func recv_indicatepkt\n"));
3212
3213                                 rtw_recv_indicatepkt(padapter, prframe);
3214                                 return _SUCCESS;
3215
3216                         }
3217
3218 #ifdef DBG_RX_DROP_FRAME
3219                         RTW_INFO("DBG_RX_DROP_FRAME %s pattrib->qos !=1\n", __FUNCTION__);
3220 #endif
3221
3222                         return _FAIL;
3223
3224                 }
3225
3226                 if (preorder_ctrl->enable == _FALSE) {
3227                         /* indicate this recv_frame                      */
3228                         preorder_ctrl->indicate_seq = pattrib->seq_num;
3229 #ifdef DBG_RX_SEQ
3230                         RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3231                                  preorder_ctrl->indicate_seq, pattrib->seq_num);
3232 #endif
3233
3234                         rtw_recv_indicatepkt(padapter, prframe);
3235
3236                         preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096;
3237 #ifdef DBG_RX_SEQ
3238                         RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3239                                  preorder_ctrl->indicate_seq, pattrib->seq_num);
3240 #endif
3241
3242                         return _SUCCESS;
3243                 }
3244
3245 #ifndef CONFIG_RECV_REORDERING_CTRL
3246                 /* indicate this recv_frame */
3247                 rtw_recv_indicatepkt(padapter, prframe);
3248                 return _SUCCESS;
3249 #endif
3250
3251         } else if (pattrib->amsdu == 1) { /* temp filter->means didn't support A-MSDUs in a A-MPDU */
3252                 if (preorder_ctrl->enable == _FALSE) {
3253                         preorder_ctrl->indicate_seq = pattrib->seq_num;
3254 #ifdef DBG_RX_SEQ
3255                         RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3256                                  preorder_ctrl->indicate_seq, pattrib->seq_num);
3257 #endif
3258
3259                         retval = amsdu_to_msdu(padapter, prframe);
3260
3261                         preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096;
3262 #ifdef DBG_RX_SEQ
3263                         RTW_INFO("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3264                                  preorder_ctrl->indicate_seq, pattrib->seq_num);
3265 #endif
3266
3267                         if (retval != _SUCCESS) {
3268 #ifdef DBG_RX_DROP_FRAME
3269                                 RTW_INFO("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__);
3270 #endif
3271                         }
3272
3273                         return retval;
3274                 }
3275         } else {
3276
3277         }
3278
3279         _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3280
3281         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
3282                  ("recv_indicatepkt_reorder: indicate=%d seq=%d\n",
3283                   preorder_ctrl->indicate_seq, pattrib->seq_num));
3284
3285         /* s2. check if winstart_b(indicate_seq) needs to been updated */
3286         if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
3287                 pdbgpriv->dbg_rx_ampdu_drop_count++;
3288                 /* pHTInfo->RxReorderDropCounter++; */
3289                 /* ReturnRFDList(Adapter, pRfd); */
3290                 /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("RxReorderIndicatePacket() ==> Packet Drop!!\n")); */
3291                 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3292                 /* return _FAIL; */
3293
3294 #ifdef DBG_RX_DROP_FRAME
3295                 RTW_INFO("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __FUNCTION__);
3296 #endif
3297 #if 0
3298                 rtw_recv_indicatepkt(padapter, prframe);
3299
3300                 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3301
3302                 goto _success_exit;
3303 #else
3304                 goto _err_exit;
3305 #endif
3306         }
3307
3308
3309         /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
3310         if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) {
3311                 /* DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); */
3312                 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3313                 /* return _FAIL; */
3314 #ifdef DBG_RX_DROP_FRAME
3315                 RTW_INFO("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __FUNCTION__);
3316 #endif
3317                 goto _err_exit;
3318         }
3319
3320
3321         /* s4. */
3322         /* Indication process. */
3323         /* After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
3324         /* with the SeqNum smaller than latest WinStart and buffer other packets. */
3325         /*  */
3326         /* For Rx Reorder condition: */
3327         /* 1. All packets with SeqNum smaller than WinStart => Indicate */
3328         /* 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
3329         /*  */
3330
3331         /* recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE); */
3332         if (recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE) == _TRUE) {
3333                 if (!preorder_ctrl->bReorderWaiting) {
3334                         preorder_ctrl->bReorderWaiting = _TRUE;
3335                         _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3336                 }
3337                 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3338         } else {
3339                 preorder_ctrl->bReorderWaiting = _FALSE;
3340                 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3341                 _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
3342         }
3343
3344
3345 _success_exit:
3346
3347         return _SUCCESS;
3348
3349 _err_exit:
3350
3351         _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3352
3353         return _FAIL;
3354 }
3355
3356
3357 void rtw_reordering_ctrl_timeout_handler(void *pcontext)
3358 {
3359         _irqL irql;
3360         struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
3361         _adapter *padapter = preorder_ctrl->padapter;
3362         _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3363
3364
3365         if (RTW_CANNOT_RUN(padapter))
3366                 return;
3367
3368         /* RTW_INFO("+rtw_reordering_ctrl_timeout_handler()=>\n"); */
3369
3370         _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3371
3372         if (preorder_ctrl)
3373                 preorder_ctrl->bReorderWaiting = _FALSE;
3374
3375         if (recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE) == _TRUE)
3376                 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3377
3378         _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3379
3380 }
3381
3382 int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe);
3383 int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe)
3384 {
3385         int retval = _SUCCESS;
3386         /* struct recv_priv *precvpriv = &padapter->recvpriv; */
3387         /* struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; */
3388         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
3389 #ifdef CONFIG_TDLS
3390         struct sta_info *psta = prframe->u.hdr.psta;
3391 #endif /* CONFIG_TDLS */
3392
3393 #ifdef CONFIG_80211N_HT
3394
3395         struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
3396
3397         DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate);
3398
3399 #ifdef CONFIG_TDLS
3400         if ((phtpriv->ht_option == _TRUE) ||
3401             ((psta->tdls_sta_state & TDLS_LINKED_STATE) &&
3402              (psta->htpriv.ht_option == _TRUE) &&
3403              (psta->htpriv.ampdu_enable == _TRUE))) /* B/G/N Mode */
3404 #else
3405         if (phtpriv->ht_option == _TRUE) /* B/G/N Mode */
3406 #endif /* CONFIG_TDLS */
3407         {
3408                 /* prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
3409
3410                 if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) { /* including perform A-MPDU Rx Ordering Buffer Control */
3411 #ifdef DBG_RX_DROP_FRAME
3412                         RTW_INFO("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __FUNCTION__);
3413 #endif
3414
3415                         if (!RTW_CANNOT_RUN(padapter))  {
3416                                 retval = _FAIL;
3417                                 return retval;
3418                         }
3419                 }
3420         } else /* B/G mode */
3421 #endif
3422         {
3423                 retval = wlanhdr_to_ethhdr(prframe);
3424                 if (retval != _SUCCESS) {
3425                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n"));
3426 #ifdef DBG_RX_DROP_FRAME
3427                         RTW_INFO("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __FUNCTION__);
3428 #endif
3429                         return retval;
3430                 }
3431
3432                 if (!RTW_CANNOT_RUN(padapter)) {
3433                         /* indicate this recv_frame */
3434                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n"));
3435                         rtw_recv_indicatepkt(padapter, prframe);
3436                 } else {
3437                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n"));
3438
3439                         RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)"
3440                                 , rtw_is_drv_stopped(padapter) ? "True" : "False"
3441                                 , rtw_is_surprise_removed(padapter) ? "True" : "False"));
3442                         retval = _FAIL;
3443                         return retval;
3444                 }
3445
3446         }
3447
3448         return retval;
3449
3450 }
3451
3452 #ifdef CONFIG_MP_INCLUDED
3453 int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
3454 {
3455         int ret = _SUCCESS;
3456         u8 *ptr = precv_frame->u.hdr.rx_data;
3457         u8 type, subtype;
3458         struct mp_priv *pmppriv = &adapter->mppriv;
3459         struct mp_tx            *pmptx;
3460
3461         pmptx = &pmppriv->tx;
3462
3463 #if 0
3464         if (1) {
3465                 u8 bDumpRxPkt;
3466                 type =  GetFrameType(ptr);
3467                 subtype = GetFrameSubType(ptr); /* bit(7)~bit(2)         */
3468
3469                 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
3470                 if (bDumpRxPkt == 1) { /* dump all rx packets */
3471                         int i;
3472                         RTW_INFO("############ type:0x%02x subtype:0x%02x #################\n", type, subtype);
3473
3474                         for (i = 0; i < 64; i = i + 8)
3475                                 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
3476                                         *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
3477                         RTW_INFO("#############################\n");
3478                 }
3479         }
3480 #endif
3481         if (pmppriv->bloopback) {
3482                 if (_rtw_memcmp(ptr + 24, pmptx->buf + 24, precv_frame->u.hdr.len - 24) == _FALSE) {
3483                         RTW_INFO("Compare payload content Fail !!!\n");
3484                         ret = _FAIL;
3485                 }
3486         }
3487
3488         if (!adapter->mppriv.bmac_filter)
3489                 return ret;
3490
3491         if (_rtw_memcmp(GetAddr2Ptr(ptr), adapter->mppriv.mac_filter, ETH_ALEN) == _FALSE)
3492                 ret = _FAIL;
3493
3494         return ret;
3495 }
3496 #endif
3497
3498 static sint MPwlanhdr_to_ethhdr(union recv_frame *precvframe)
3499 {
3500         sint    rmv_len;
3501         u16 eth_type, len;
3502         u8      bsnaphdr;
3503         u8      *psnap_type;
3504         u8 mcastheadermac[] = {0x01, 0x00, 0x5e};
3505
3506         struct ieee80211_snap_hdr       *psnap;
3507
3508         sint ret = _SUCCESS;
3509         _adapter                        *adapter = precvframe->u.hdr.adapter;
3510         struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
3511
3512         u8      *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
3513         struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
3514
3515         _func_enter_;
3516
3517         if (pattrib->encrypt)
3518                 recvframe_pull_tail(precvframe, pattrib->icv_len);
3519
3520         psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
3521         psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
3522         /* convert hdr + possible LLC headers into Ethernet header */
3523         /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
3524         if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
3525              (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) &&
3526              (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) ||
3527             /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
3528             _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
3529                 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
3530                 bsnaphdr = _TRUE;
3531         } else {
3532                 /* Leave Ethernet header part of hdr and full payload */
3533                 bsnaphdr = _FALSE;
3534         }
3535
3536         rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
3537         len = precvframe->u.hdr.len - rmv_len;
3538
3539         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n===pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n\n", pattrib->hdrlen,        pattrib->iv_len));
3540
3541         _rtw_memcpy(&eth_type, ptr + rmv_len, 2);
3542         eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
3543         pattrib->eth_type = eth_type;
3544
3545         {
3546                 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
3547         }
3548
3549         _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
3550         _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
3551
3552         if (!bsnaphdr) {
3553                 len = htons(len);
3554                 _rtw_memcpy(ptr + 12, &len, 2);
3555         }
3556
3557
3558         len = htons(pattrib->seq_num);
3559         /* RTW_INFO("wlan seq = %d ,seq_num =%x\n",len,pattrib->seq_num); */
3560         _rtw_memcpy(ptr + 12, &len, 2);
3561         if (adapter->mppriv.bRTWSmbCfg == _TRUE) {
3562                 /* if(_rtw_memcmp(mcastheadermac, pattrib->dst, 3) == _TRUE) */ /* SimpleConfig Dest. */
3563                 /*                      _rtw_memcpy(ptr+ETH_ALEN, pattrib->bssid, ETH_ALEN); */
3564
3565                 if (_rtw_memcmp(mcastheadermac, pattrib->bssid, 3) == _TRUE) /* SimpleConfig Dest. */
3566                         _rtw_memcpy(ptr, pattrib->bssid, ETH_ALEN);
3567
3568         }
3569
3570
3571         _func_exit_;
3572         return ret;
3573
3574 }
3575
3576
3577 int mp_recv_frame(_adapter *padapter, union recv_frame *rframe)
3578 {
3579         int ret = _SUCCESS;
3580         struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
3581         struct recv_priv *precvpriv = &padapter->recvpriv;
3582         _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3583 #ifdef CONFIG_MP_INCLUDED
3584         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3585         struct mp_priv *pmppriv = &padapter->mppriv;
3586 #endif /* CONFIG_MP_INCLUDED */
3587         u8 type;
3588         u8 *ptr = rframe->u.hdr.rx_data;
3589         u8 *psa, *pda, *pbssid;
3590         struct sta_info *psta = NULL;
3591         DBG_COUNTER(padapter->rx_logs.core_rx_pre);
3592
3593         if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { /* &&(padapter->mppriv.check_mp_pkt == 0)) */
3594                 if (pattrib->crc_err == 1)
3595                         padapter->mppriv.rx_crcerrpktcount++;
3596                 else {
3597                         if (_SUCCESS == validate_mp_recv_frame(padapter, rframe))
3598                                 padapter->mppriv.rx_pktcount++;
3599                         else
3600                                 padapter->mppriv.rx_pktcount_filter_out++;
3601                 }
3602
3603                 if (pmppriv->rx_bindicatePkt == _FALSE) {
3604                         /* RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("MP - Not in loopback mode , drop pkt\n")); */
3605                         ret = _FAIL;
3606                         rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3607                         goto exit;
3608                 } else {
3609                         type =  GetFrameType(ptr);
3610                         pattrib->to_fr_ds = get_tofr_ds(ptr);
3611                         pattrib->frag_num = GetFragNum(ptr);
3612                         pattrib->seq_num = GetSequence(ptr);
3613                         pattrib->pw_save = GetPwrMgt(ptr);
3614                         pattrib->mfrag = GetMFrag(ptr);
3615                         pattrib->mdata = GetMData(ptr);
3616                         pattrib->privacy = GetPrivacy(ptr);
3617                         pattrib->order = GetOrder(ptr);
3618
3619                         if (type == WIFI_DATA_TYPE) {
3620                                 pda = get_da(ptr);
3621                                 psa = get_sa(ptr);
3622                                 pbssid = get_hdr_bssid(ptr);
3623
3624                                 _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
3625                                 _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
3626                                 _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
3627
3628                                 switch (pattrib->to_fr_ds) {
3629                                 case 0:
3630                                         _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
3631                                         _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
3632                                         ret = sta2sta_data_frame(padapter, rframe, &psta);
3633                                         break;
3634
3635                                 case 1:
3636
3637                                         _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
3638                                         _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
3639                                         ret = ap2sta_data_frame(padapter, rframe, &psta);
3640
3641                                         break;
3642
3643                                 case 2:
3644                                         _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
3645                                         _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
3646                                         ret = sta2ap_data_frame(padapter, rframe, &psta);
3647                                         break;
3648
3649                                 case 3:
3650                                         _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
3651                                         _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
3652                                         ret = _FAIL;
3653                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n"));
3654                                         break;
3655
3656                                 default:
3657                                         ret = _FAIL;
3658                                         break;
3659                                 }
3660
3661                                 ret = MPwlanhdr_to_ethhdr(rframe);
3662
3663                                 if (ret != _SUCCESS) {
3664                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n"));
3665 #ifdef DBG_RX_DROP_FRAME
3666                                         RTW_INFO("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr: drop pkt\n", __FUNCTION__);
3667 #endif
3668                                         rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3669                                         ret = _FAIL;
3670                                         goto exit;
3671                                 }
3672                                 if (!RTW_CANNOT_RUN(padapter)) {
3673                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_func: recv_func rtw_recv_indicatepkt\n"));
3674                                         /* indicate this recv_frame */
3675                                         ret = rtw_recv_indicatepkt(padapter, rframe);
3676                                         if (ret != _SUCCESS) {
3677 #ifdef DBG_RX_DROP_FRAME
3678                                                 RTW_INFO("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__);
3679 #endif
3680                                                 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3681                                                 ret = _FAIL;
3682
3683                                                 goto exit;
3684                                         }
3685                                 } else {
3686                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@  recv_func: rtw_free_recvframe\n"));
3687                                         RT_TRACE(_module_rtl871x_recv_c_, _drv_debug_, ("recv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)"
3688                                                 , rtw_is_drv_stopped(padapter) ? "True" : "False"
3689                                                 , rtw_is_surprise_removed(padapter) ? "True" : "False"));
3690 #ifdef DBG_RX_DROP_FRAME
3691                                         RTW_INFO("DBG_RX_DROP_FRAME %s ecv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)\n", __func__,
3692                                                 rtw_is_drv_stopped(padapter) ? "True" : "False",
3693                                                 rtw_is_surprise_removed(padapter) ? "True" : "False");
3694 #endif
3695                                         ret = _FAIL;
3696                                         rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3697                                         goto exit;
3698                                 }
3699
3700                         }
3701                 }
3702
3703         }
3704
3705         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n"));
3706         rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3707         ret = _FAIL;
3708
3709 exit:
3710         return ret;
3711
3712 }
3713
3714 static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u8 *buf)
3715 {
3716 #define CHAN2FREQ(a) ((a < 14) ? (2407+5*a) : (5000+5*a))
3717
3718 #if 0
3719 #define RTW_RX_RADIOTAP_PRESENT (\
3720                                  (1 << IEEE80211_RADIOTAP_TSFT)              | \
3721                                  (1 << IEEE80211_RADIOTAP_FLAGS)             | \
3722                                  (1 << IEEE80211_RADIOTAP_RATE)              | \
3723                                  (1 << IEEE80211_RADIOTAP_CHANNEL)           | \
3724                                  (0 << IEEE80211_RADIOTAP_FHSS)              | \
3725                                  (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)     | \
3726                                  (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)      | \
3727                                  (0 << IEEE80211_RADIOTAP_LOCK_QUALITY)      | \
3728                                  (0 << IEEE80211_RADIOTAP_TX_ATTENUATION)    | \
3729                                  (0 << IEEE80211_RADIOTAP_DB_TX_ATTENUATION) | \
3730                                  (0 << IEEE80211_RADIOTAP_DBM_TX_POWER)      | \
3731                                  (1 << IEEE80211_RADIOTAP_ANTENNA)           | \
3732                                  (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)      | \
3733                                  (0 << IEEE80211_RADIOTAP_DB_ANTNOISE)       | \
3734                                  (0 << IEEE80211_RADIOTAP_RX_FLAGS)          | \
3735                                  (0 << IEEE80211_RADIOTAP_TX_FLAGS)          | \
3736                                  (0 << IEEE80211_RADIOTAP_RTS_RETRIES)       | \
3737                                  (0 << IEEE80211_RADIOTAP_DATA_RETRIES)      | \
3738                                  (0 << IEEE80211_RADIOTAP_MCS)               | \
3739                                  (0 << IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)| \
3740                                  (0 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE)  | \
3741                                  (0 << IEEE80211_RADIOTAP_EXT)               | \
3742                                  0)
3743
3744         /* (0 << IEEE80211_RADIOTAP_AMPDU_STATUS)      | \ */
3745         /* (0 << IEEE80211_RADIOTAP_VHT)               | \ */
3746 #endif
3747 #ifndef IEEE80211_RADIOTAP_MCS
3748 #define IEEE80211_RADIOTAP_MCS 19
3749 #endif
3750 #ifndef IEEE80211_RADIOTAP_VHT
3751 #define IEEE80211_RADIOTAP_VHT 21
3752 #endif
3753
3754 #ifndef IEEE80211_RADIOTAP_F_BADFCS
3755 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */
3756 #endif
3757
3758         sint ret = _SUCCESS;
3759         _adapter                        *adapter = precvframe->u.hdr.adapter;
3760         struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
3761         struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
3762
3763         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3764
3765         u16 tmp_16bit = 0;
3766
3767         u8 data_rate[] = {
3768                 2, 4, 11, 22, /* CCK */
3769                 12, 18, 24, 36, 48, 72, 93, 108, /* OFDM */
3770                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* HT MCS index */
3771                 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3772                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 1 */
3773                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 2 */
3774                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 3 */
3775                 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 4 */
3776         };
3777
3778         _pkt *pskb = NULL;
3779
3780         struct ieee80211_radiotap_header *rtap_hdr = NULL;
3781         u8 *ptr = NULL;
3782
3783         u8 hdr_buf[64] = {0};
3784         u16 rt_len = 8;
3785
3786         /* create header */
3787         rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0];
3788         rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
3789
3790         /* tsft */
3791         if (pattrib->tsfl) {
3792                 u64 tmp_64bit;
3793
3794                 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_TSFT);
3795                 tmp_64bit = cpu_to_le64(pattrib->tsfl);
3796                 memcpy(&hdr_buf[rt_len], &tmp_64bit, 8);
3797                 rt_len += 8;
3798         }
3799
3800         /* flags */
3801         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS);
3802         if (0)
3803                 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_CFP;
3804
3805         if (0)
3806                 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_SHORTPRE;
3807
3808         if ((pattrib->encrypt == 1) || (pattrib->encrypt == 5))
3809                 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_WEP;
3810
3811         if (pattrib->mfrag)
3812                 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FRAG;
3813
3814         /* always append FCS */
3815         hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS;
3816
3817
3818         if (0)
3819                 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_DATAPAD;
3820
3821         if (pattrib->crc_err)
3822                 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_BADFCS;
3823
3824         if (pattrib->sgi) {
3825                 /* Currently unspecified but used */
3826                 hdr_buf[rt_len] |= 0x80;
3827         }
3828         rt_len += 1;
3829
3830         /* rate */
3831         if (pattrib->data_rate < 12) {
3832                 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE);
3833                 if (pattrib->data_rate < 4) {
3834                         /* CCK */
3835                         hdr_buf[rt_len] = data_rate[pattrib->data_rate];
3836                 } else {
3837                         /* OFDM */
3838                         hdr_buf[rt_len] = data_rate[pattrib->data_rate];
3839                 }
3840         }
3841         rt_len += 1; /* force padding 1 byte for aligned */
3842
3843         /* channel */
3844         tmp_16bit = 0;
3845         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
3846         tmp_16bit = CHAN2FREQ(rtw_get_oper_ch(padapter));
3847         /*tmp_16bit = CHAN2FREQ(pHalData->CurrentChannel);*/
3848         memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
3849         rt_len += 2;
3850
3851         /* channel flags */
3852         tmp_16bit = 0;
3853         if (pHalData->CurrentBandType == 0)
3854                 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_2GHZ);
3855         else
3856                 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_5GHZ);
3857
3858         if (pattrib->data_rate < 12) {
3859                 if (pattrib->data_rate < 4) {
3860                         /* CCK */
3861                         tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_CCK);
3862                 } else {
3863                         /* OFDM */
3864                         tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_OFDM);
3865                 }
3866         } else
3867                 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_DYN);
3868         memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
3869         rt_len += 2;
3870
3871         /* dBm Antenna Signal */
3872         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
3873         hdr_buf[rt_len] = pattrib->phy_info.RecvSignalPower;
3874         rt_len += 1;
3875
3876 #if 0
3877         /* dBm Antenna Noise */
3878         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
3879         hdr_buf[rt_len] = 0;
3880         rt_len += 1;
3881
3882         /* Signal Quality */
3883         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_LOCK_QUALITY);
3884         hdr_buf[rt_len] = pattrib->phy_info.SignalQuality;
3885         rt_len += 1;
3886 #endif
3887
3888         /* Antenna */
3889         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA);
3890         hdr_buf[rt_len] = 0; /* pHalData->rf_type; */
3891         rt_len += 1;
3892
3893         /* RX flags */
3894         rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RX_FLAGS);
3895 #if 0
3896         tmp_16bit = cpu_to_le16(0);
3897         memcpy(ptr, &tmp_16bit, 1);
3898 #endif
3899         rt_len += 2;
3900
3901         /* MCS information */
3902         if (pattrib->data_rate >= 12 && pattrib->data_rate < 44) {
3903                 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS);
3904                 /* known, flag */
3905                 hdr_buf[rt_len] |= BIT1; /* MCS index known */
3906
3907                 /* bandwidth */
3908                 hdr_buf[rt_len] |= BIT0;
3909                 hdr_buf[rt_len + 1] |= (pattrib->bw & 0x03);
3910
3911                 /* guard interval */
3912                 hdr_buf[rt_len] |= BIT2;
3913                 hdr_buf[rt_len + 1] |= (pattrib->sgi & 0x01) << 2;
3914
3915                 /* STBC */
3916                 hdr_buf[rt_len] |= BIT5;
3917                 hdr_buf[rt_len + 1] |= (pattrib->stbc & 0x03) << 5;
3918
3919                 rt_len += 2;
3920
3921                 /* MCS rate index */
3922                 hdr_buf[rt_len] = data_rate[pattrib->data_rate];
3923                 rt_len += 1;
3924         }
3925
3926         /* VHT */
3927         if (pattrib->data_rate >= 44 && pattrib->data_rate < 84) {
3928                 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT);
3929
3930                 /* known 16 bit, flag 8 bit */
3931                 tmp_16bit = 0;
3932
3933                 /* Bandwidth */
3934                 tmp_16bit |= BIT6;
3935
3936                 /* Group ID */
3937                 tmp_16bit |= BIT7;
3938
3939                 /* Partial AID */
3940                 tmp_16bit |= BIT8;
3941
3942                 /* STBC */
3943                 tmp_16bit |= BIT0;
3944                 hdr_buf[rt_len + 2] |= (pattrib->stbc & 0x01);
3945
3946                 /* Guard interval */
3947                 tmp_16bit |= BIT2;
3948                 hdr_buf[rt_len + 2] |= (pattrib->sgi & 0x01) << 2;
3949
3950                 /* LDPC extra OFDM symbol */
3951                 tmp_16bit |= BIT4;
3952                 hdr_buf[rt_len + 2] |= (pattrib->ldpc & 0x01) << 4;
3953
3954                 memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
3955                 rt_len += 3;
3956
3957                 /* bandwidth */
3958                 if (pattrib->bw == 0)
3959                         hdr_buf[rt_len] |= 0;
3960                 else if (pattrib->bw == 1)
3961                         hdr_buf[rt_len] |= 1;
3962                 else if (pattrib->bw == 2)
3963                         hdr_buf[rt_len] |= 4;
3964                 else if (pattrib->bw == 3)
3965                         hdr_buf[rt_len] |= 11;
3966                 rt_len += 1;
3967
3968                 /* mcs_nss */
3969                 if (pattrib->data_rate >= 44 && pattrib->data_rate < 54) {
3970                         hdr_buf[rt_len] |= 1;
3971                         hdr_buf[rt_len] |= data_rate[pattrib->data_rate] << 4;
3972                 } else if (pattrib->data_rate >= 54 && pattrib->data_rate < 64) {
3973                         hdr_buf[rt_len + 1] |= 2;
3974                         hdr_buf[rt_len + 1] |= data_rate[pattrib->data_rate] << 4;
3975                 } else if (pattrib->data_rate >= 64 && pattrib->data_rate < 74) {
3976                         hdr_buf[rt_len + 2] |= 3;
3977                         hdr_buf[rt_len + 2] |= data_rate[pattrib->data_rate] << 4;
3978                 } else if (pattrib->data_rate >= 74 && pattrib->data_rate < 84) {
3979                         hdr_buf[rt_len + 3] |= 4;
3980                         hdr_buf[rt_len + 3] |= data_rate[pattrib->data_rate] << 4;
3981                 }
3982                 rt_len += 4;
3983
3984                 /* coding */
3985                 hdr_buf[rt_len] = 0;
3986                 rt_len += 1;
3987
3988                 /* group_id */
3989                 hdr_buf[rt_len] = 0;
3990                 rt_len += 1;
3991
3992                 /* partial_aid */
3993                 tmp_16bit = 0;
3994                 memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
3995                 rt_len += 2;
3996         }
3997
3998         /* push to skb */
3999         pskb = (_pkt *)buf;
4000         if (skb_headroom(pskb) < rt_len) {
4001                 RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__);
4002                 ret = _FAIL;
4003                 return ret;
4004         }
4005
4006         ptr = skb_push(pskb, rt_len);
4007         if (ptr) {
4008                 rtap_hdr->it_len = cpu_to_le16(rt_len);
4009                 memcpy(ptr, rtap_hdr, rt_len);
4010         } else
4011                 ret = _FAIL;
4012
4013         return ret;
4014
4015 }
4016
4017 int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe)
4018 {
4019         int ret = _SUCCESS;
4020         struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
4021         struct recv_priv *precvpriv = &padapter->recvpriv;
4022         _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4023         _pkt *pskb = NULL;
4024
4025         /* read skb information from recv frame */
4026         pskb = rframe->u.hdr.pkt;
4027         pskb->len = rframe->u.hdr.len;
4028         pskb->data = rframe->u.hdr.rx_data;
4029         skb_set_tail_pointer(pskb, rframe->u.hdr.len);
4030
4031         /* fill radiotap header */
4032         if (fill_radiotap_hdr(padapter, rframe, (u8 *)pskb) == _FAIL) {
4033                 ret = _FAIL;
4034                 rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4035                 goto exit;
4036         }
4037
4038         /* write skb information to recv frame */
4039         skb_reset_mac_header(pskb);
4040         rframe->u.hdr.len = pskb->len;
4041         rframe->u.hdr.rx_data = pskb->data;
4042         rframe->u.hdr.rx_head = pskb->head;
4043         rframe->u.hdr.rx_tail = skb_tail_pointer(pskb);
4044         rframe->u.hdr.rx_end = skb_end_pointer(pskb);
4045
4046         if (!RTW_CANNOT_RUN(padapter)) {
4047                 /* indicate this recv_frame */
4048                 ret = rtw_recv_monitor(padapter, rframe);
4049                 if (ret != _SUCCESS) {
4050                         ret = _FAIL;
4051                         rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4052                         goto exit;
4053                 }
4054         } else {
4055                 ret = _FAIL;
4056                 rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4057                 goto exit;
4058         }
4059
4060 exit:
4061         return ret;
4062 }
4063
4064 int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
4065 {
4066         int ret = _SUCCESS;
4067         struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
4068         struct recv_priv *precvpriv = &padapter->recvpriv;
4069         _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4070
4071 #ifdef DBG_RX_COUNTER_DUMP
4072         if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
4073                 if (pattrib->crc_err == 1)
4074                         padapter->drv_rx_cnt_crcerror++;
4075                 else
4076                         padapter->drv_rx_cnt_ok++;
4077         }
4078 #endif
4079
4080 #ifdef CONFIG_MP_INCLUDED
4081         if (padapter->registrypriv.mp_mode == 1 || padapter->mppriv.bRTWSmbCfg == _TRUE) {
4082                 mp_recv_frame(padapter, rframe);
4083                 ret = _FAIL;
4084                 goto exit;
4085         } else
4086 #endif
4087         {
4088                 /* check the frame crtl field and decache */
4089                 ret = validate_recv_frame(padapter, rframe);
4090                 if (ret != _SUCCESS) {
4091                         RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n"));
4092                         rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
4093                         goto exit;
4094                 }
4095         }
4096 exit:
4097         return ret;
4098 }
4099
4100 /*#define DBG_RX_BMC_FRAME*/
4101 int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
4102 {
4103         int ret = _SUCCESS;
4104         union recv_frame *orig_prframe = prframe;
4105         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
4106         struct recv_priv *precvpriv = &padapter->recvpriv;
4107         _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4108 #ifdef CONFIG_TDLS
4109         u8 *psnap_type, *pcategory;
4110 #endif /* CONFIG_TDLS */
4111
4112         DBG_COUNTER(padapter->rx_logs.core_rx_post);
4113
4114         /* DATA FRAME */
4115         rtw_led_control(padapter, LED_CTL_RX);
4116
4117         prframe = decryptor(padapter, prframe);
4118         if (prframe == NULL) {
4119                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decryptor: drop pkt\n"));
4120 #ifdef DBG_RX_DROP_FRAME
4121                 RTW_INFO("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __FUNCTION__);
4122 #endif
4123                 ret = _FAIL;
4124                 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err);
4125                 goto _recv_data_drop;
4126         }
4127
4128 #ifdef DBG_RX_BMC_FRAME
4129         if (IS_MCAST(pattrib->ra)) {
4130                 u8 *pbuf = prframe->u.hdr.rx_data;
4131                 u8 *sa_addr = get_sa(pbuf);
4132
4133                 RTW_INFO("%s =>"ADPT_FMT" Rx BC/MC from MAC: "MAC_FMT"\n", __func__, ADPT_ARG(padapter), MAC_ARG(sa_addr));
4134         }
4135 #endif
4136
4137 #if 0
4138         if (padapter->adapter_type == PRIMARY_ADAPTER) {
4139                 RTW_INFO("+++\n");
4140                 {
4141                         int i;
4142                         u8      *ptr = get_recvframe_data(prframe);
4143                         for (i = 0; i < 140; i = i + 8)
4144                                 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr + i),
4145                                         *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
4146
4147                 }
4148                 RTW_INFO("---\n");
4149         }
4150 #endif
4151
4152 #ifdef CONFIG_TDLS
4153         /* check TDLS frame */
4154         psnap_type = get_recvframe_data(orig_prframe) + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
4155         pcategory = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
4156
4157         if ((_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, ETH_TYPE_LEN)) &&
4158             ((*pcategory == RTW_WLAN_CATEGORY_TDLS) || (*pcategory == RTW_WLAN_CATEGORY_P2P))) {
4159                 ret = OnTDLS(padapter, prframe);
4160                 if (ret == _FAIL)
4161                         goto _exit_recv_func;
4162         }
4163 #endif /* CONFIG_TDLS */
4164
4165         prframe = recvframe_chk_defrag(padapter, prframe);
4166         if (prframe == NULL)    {
4167                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chk_defrag: drop pkt\n"));
4168 #ifdef DBG_RX_DROP_FRAME
4169                 RTW_INFO("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __FUNCTION__);
4170 #endif
4171                 DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err);
4172                 goto _recv_data_drop;
4173         }
4174
4175         prframe = portctrl(padapter, prframe);
4176         if (prframe == NULL) {
4177                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("portctrl: drop pkt\n"));
4178 #ifdef DBG_RX_DROP_FRAME
4179                 RTW_INFO("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __FUNCTION__);
4180 #endif
4181                 ret = _FAIL;
4182                 DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err);
4183                 goto _recv_data_drop;
4184         }
4185
4186         count_rx_stats(padapter, prframe, NULL);
4187
4188 #ifdef CONFIG_WAPI_SUPPORT
4189         rtw_wapi_update_info(padapter, prframe);
4190 #endif
4191
4192 #ifdef CONFIG_80211N_HT
4193         ret = process_recv_indicatepkts(padapter, prframe);
4194         if (ret != _SUCCESS) {
4195                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recv_func: process_recv_indicatepkts fail!\n"));
4196 #ifdef DBG_RX_DROP_FRAME
4197                 RTW_INFO("DBG_RX_DROP_FRAME %s process_recv_indicatepkts fail!\n", __FUNCTION__);
4198 #endif
4199                 rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
4200                 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_err);
4201                 goto _recv_data_drop;
4202         }
4203 #else /* CONFIG_80211N_HT */
4204         if (!pattrib->amsdu) {
4205                 ret = wlanhdr_to_ethhdr(prframe);
4206                 if (ret != _SUCCESS) {
4207                         RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n"));
4208 #ifdef DBG_RX_DROP_FRAME
4209                         RTW_INFO("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr: drop pkt\n", __FUNCTION__);
4210 #endif
4211                         rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
4212                         goto _recv_data_drop;
4213                 }
4214
4215                 if (!RTW_CANNOT_RUN(padapter)) {
4216                         RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_func: recv_func rtw_recv_indicatepkt\n"));
4217                         /* indicate this recv_frame */
4218                         ret = rtw_recv_indicatepkt(padapter, prframe);
4219                         if (ret != _SUCCESS) {
4220 #ifdef DBG_RX_DROP_FRAME
4221                                 RTW_INFO("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__);
4222 #endif
4223                                 goto _recv_data_drop;
4224                         }
4225                 } else {
4226                         RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@  recv_func: rtw_free_recvframe\n"));
4227                         RT_TRACE(_module_rtl871x_recv_c_, _drv_debug_, ("recv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)"
4228                                 , rtw_is_drv_stopped(padapter) ? "True" : "False"
4229                                 , rtw_is_surprise_removed(padapter) ? "True" : "False"));
4230
4231 #ifdef DBG_RX_DROP_FRAME
4232                         RTW_INFO("DBG_RX_DROP_FRAME %s recv_func:bDriverStopped(%s) OR bSurpriseRemoved(%s)\n", __func__
4233                                 , rtw_is_drv_stopped(padapter) ? "True" : "False"
4234                                 , rtw_is_surprise_removed(padapter) ? "True" : "False");
4235 #endif
4236                         ret = _FAIL;
4237                         rtw_free_recvframe(orig_prframe, pfree_recv_queue); /* free this recv_frame */
4238                 }
4239
4240         } else if (pattrib->amsdu == 1) {
4241
4242                 ret = amsdu_to_msdu(padapter, prframe);
4243                 if (ret != _SUCCESS) {
4244 #ifdef DBG_RX_DROP_FRAME
4245                         RTW_INFO("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__);
4246 #endif
4247                         rtw_free_recvframe(orig_prframe, pfree_recv_queue);
4248                         goto _recv_data_drop;
4249                 }
4250         } else {
4251 #ifdef DBG_RX_DROP_FRAME
4252                 RTW_INFO("DBG_RX_DROP_FRAME %s what is this condition??\n", __FUNCTION__);
4253 #endif
4254                 goto _recv_data_drop;
4255         }
4256 #endif /* CONFIG_80211N_HT */
4257
4258 _exit_recv_func:
4259         return ret;
4260
4261 _recv_data_drop:
4262         precvpriv->rx_drop++;
4263         return ret;
4264 }
4265
4266
4267 int recv_func(_adapter *padapter, union recv_frame *rframe);
4268 int recv_func(_adapter *padapter, union recv_frame *rframe)
4269 {
4270         int ret;
4271         struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
4272         struct recv_priv *recvpriv = &padapter->recvpriv;
4273         struct security_priv *psecuritypriv = &padapter->securitypriv;
4274         struct mlme_priv *mlmepriv = &padapter->mlmepriv;
4275
4276         if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE)) {
4277                 /* monitor mode */
4278                 recv_frame_monitor(padapter, rframe);
4279                 ret = _SUCCESS;
4280                 goto exit;
4281         } else
4282
4283                 /* check if need to handle uc_swdec_pending_queue*/
4284                 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) {
4285                         union recv_frame *pending_frame;
4286                         int cnt = 0;
4287
4288                         while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) {
4289                                 cnt++;
4290                                 DBG_COUNTER(padapter->rx_logs.core_rx_dequeue);
4291                                 recv_func_posthandle(padapter, pending_frame);
4292                         }
4293
4294                         if (cnt)
4295                                 RTW_INFO(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n",
4296                                          FUNC_ADPT_ARG(padapter), cnt);
4297                 }
4298
4299         DBG_COUNTER(padapter->rx_logs.core_rx);
4300         ret = recv_func_prehandle(padapter, rframe);
4301
4302         if (ret == _SUCCESS) {
4303
4304                 /* check if need to enqueue into uc_swdec_pending_queue*/
4305                 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
4306                     !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 &&
4307                     (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt == _TRUE) &&
4308                     psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
4309                     !psecuritypriv->busetkipkey) {
4310                         DBG_COUNTER(padapter->rx_logs.core_rx_enqueue);
4311                         rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
4312                         /* RTW_INFO("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); */
4313
4314                         if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) {
4315                                 /* to prevent from recvframe starvation, get recvframe from uc_swdec_pending_queue to free_recvframe_cnt */
4316                                 rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
4317                                 if (rframe)
4318                                         goto do_posthandle;
4319                         }
4320                         goto exit;
4321                 }
4322
4323 do_posthandle:
4324                 ret = recv_func_posthandle(padapter, rframe);
4325         }
4326
4327 exit:
4328         return ret;
4329 }
4330
4331
4332 s32 rtw_recv_entry(union recv_frame *precvframe)
4333 {
4334         _adapter *padapter;
4335         struct recv_priv *precvpriv;
4336         s32 ret = _SUCCESS;
4337
4338         _func_enter_;
4339
4340         /*      RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("+rtw_recv_entry\n")); */
4341
4342         padapter = precvframe->u.hdr.adapter;
4343
4344         precvpriv = &padapter->recvpriv;
4345
4346
4347         ret = recv_func(padapter, precvframe);
4348         if (ret == _FAIL) {
4349                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtw_recv_entry: recv_func return fail!!!\n"));
4350                 goto _recv_entry_drop;
4351         }
4352
4353
4354         precvpriv->rx_pkts++;
4355
4356         _func_exit_;
4357
4358         return ret;
4359
4360 _recv_entry_drop:
4361
4362 #ifdef CONFIG_MP_INCLUDED
4363         if (padapter->registrypriv.mp_mode == 1)
4364                 padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
4365 #endif
4366
4367         /* RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("_recv_entry_drop\n")); */
4368
4369         _func_exit_;
4370
4371         return ret;
4372 }
4373
4374 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4375 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS)
4376 {
4377         _adapter *adapter = (_adapter *)FunctionContext;
4378         struct recv_priv *recvpriv = &adapter->recvpriv;
4379
4380         u32 tmp_s, tmp_q;
4381         u8 avg_signal_strength = 0;
4382         u8 avg_signal_qual = 0;
4383         u32 num_signal_strength = 0;
4384         u32 num_signal_qual = 0;
4385         u8 ratio_pre_stat = 0, ratio_curr_stat = 0, ratio_total = 0, ratio_profile = SIGNAL_STAT_CALC_PROFILE_0;
4386
4387         if (adapter->recvpriv.is_signal_dbg) {
4388                 /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
4389                 adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
4390                 adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
4391         } else {
4392
4393                 if (recvpriv->signal_strength_data.update_req == 0) { /* update_req is clear, means we got rx */
4394                         avg_signal_strength = recvpriv->signal_strength_data.avg_val;
4395                         num_signal_strength = recvpriv->signal_strength_data.total_num;
4396                         /* after avg_vals are accquired, we can re-stat the signal values */
4397                         recvpriv->signal_strength_data.update_req = 1;
4398                 }
4399
4400                 if (recvpriv->signal_qual_data.update_req == 0) { /* update_req is clear, means we got rx */
4401                         avg_signal_qual = recvpriv->signal_qual_data.avg_val;
4402                         num_signal_qual = recvpriv->signal_qual_data.total_num;
4403                         /* after avg_vals are accquired, we can re-stat the signal values */
4404                         recvpriv->signal_qual_data.update_req = 1;
4405                 }
4406
4407                 if (num_signal_strength == 0) {
4408                         if (rtw_get_on_cur_ch_time(adapter) == 0
4409                             || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval
4410                            )
4411                                 goto set_timer;
4412                 }
4413
4414                 if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE
4415                     || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE
4416                    )
4417                         goto set_timer;
4418
4419 #ifdef CONFIG_CONCURRENT_MODE
4420                 if (rtw_mi_buddy_check_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE)
4421                         goto set_timer;
4422 #endif
4423
4424                 if (RTW_SIGNAL_STATE_CALC_PROFILE < SIGNAL_STAT_CALC_PROFILE_MAX)
4425                         ratio_profile = RTW_SIGNAL_STATE_CALC_PROFILE;
4426
4427                 ratio_pre_stat = signal_stat_calc_profile[ratio_profile][0];
4428                 ratio_curr_stat = signal_stat_calc_profile[ratio_profile][1];
4429                 ratio_total = ratio_pre_stat + ratio_curr_stat;
4430
4431                 /* update value of signal_strength, rssi, signal_qual */
4432                 tmp_s = (ratio_curr_stat * avg_signal_strength + ratio_pre_stat * recvpriv->signal_strength);
4433                 if (tmp_s % ratio_total)
4434                         tmp_s = tmp_s / ratio_total + 1;
4435                 else
4436                         tmp_s = tmp_s / ratio_total;
4437                 if (tmp_s > 100)
4438                         tmp_s = 100;
4439
4440                 tmp_q = (ratio_curr_stat * avg_signal_qual + ratio_pre_stat * recvpriv->signal_qual);
4441                 if (tmp_q % ratio_total)
4442                         tmp_q = tmp_q / ratio_total + 1;
4443                 else
4444                         tmp_q = tmp_q / ratio_total;
4445                 if (tmp_q > 100)
4446                         tmp_q = 100;
4447
4448                 recvpriv->signal_strength = tmp_s;
4449                 recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
4450                 recvpriv->signal_qual = tmp_q;
4451
4452 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
4453                 RTW_INFO(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
4454                          ", num_signal_strength:%u, num_signal_qual:%u"
4455                          ", on_cur_ch_ms:%d"
4456                          "\n"
4457                          , FUNC_ADPT_ARG(adapter)
4458                          , recvpriv->signal_strength
4459                          , recvpriv->rssi
4460                          , recvpriv->signal_qual
4461                          , num_signal_strength, num_signal_qual
4462                         , rtw_get_on_cur_ch_time(adapter) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) : 0
4463                         );
4464 #endif
4465         }
4466
4467 set_timer:
4468         rtw_set_signal_stat_timer(recvpriv);
4469
4470 }
4471 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4472
4473 static void rx_process_rssi(_adapter *padapter, union recv_frame *prframe)
4474 {
4475         u32     last_rssi, tmp_val;
4476         struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
4477 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4478         struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data;
4479 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4480
4481         /* RTW_INFO("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->RecvSignalPower,pattrib->signal_strength); */
4482         /* if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon) */
4483         {
4484 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4485                 if (signal_stat->update_req) {
4486                         signal_stat->total_num = 0;
4487                         signal_stat->total_val = 0;
4488                         signal_stat->update_req = 0;
4489                 }
4490
4491                 signal_stat->total_num++;
4492                 signal_stat->total_val  += pattrib->phy_info.SignalStrength;
4493                 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
4494 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4495
4496                 /* Adapter->RxStats.RssiCalculateCnt++;  */ /* For antenna Test */
4497                 if (padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
4498                         padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX;
4499                         last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index];
4500                         padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
4501                 }
4502                 padapter->recvpriv.signal_strength_data.total_val  += pattrib->phy_info.SignalStrength;
4503
4504                 padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->phy_info.SignalStrength;
4505                 if (padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX)
4506                         padapter->recvpriv.signal_strength_data.index = 0;
4507
4508
4509                 tmp_val = padapter->recvpriv.signal_strength_data.total_val / padapter->recvpriv.signal_strength_data.total_num;
4510
4511                 if (padapter->recvpriv.is_signal_dbg) {
4512                         padapter->recvpriv.signal_strength = padapter->recvpriv.signal_strength_dbg;
4513                         padapter->recvpriv.rssi = (s8)translate_percentage_to_dbm(padapter->recvpriv.signal_strength_dbg);
4514                 } else {
4515                         padapter->recvpriv.signal_strength = tmp_val;
4516                         padapter->recvpriv.rssi = (s8)translate_percentage_to_dbm(tmp_val);
4517                 }
4518
4519                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("UI RSSI = %d, ui_rssi.TotalVal = %d, ui_rssi.TotalNum = %d\n", tmp_val, padapter->recvpriv.signal_strength_data.total_val,
4520                         padapter->recvpriv.signal_strength_data.total_num));
4521 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4522         }
4523 }
4524
4525 static void rx_process_link_qual(_adapter *padapter, union recv_frame *prframe)
4526 {
4527         u32     last_evm = 0, tmpVal;
4528         struct rx_pkt_attrib *pattrib;
4529 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4530         struct signal_stat *signal_stat;
4531 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4532
4533         if (prframe == NULL || padapter == NULL)
4534                 return;
4535
4536         pattrib = &prframe->u.hdr.attrib;
4537 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4538         signal_stat = &padapter->recvpriv.signal_qual_data;
4539 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4540
4541         /* RTW_INFO("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual); */
4542
4543 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4544         if (signal_stat->update_req) {
4545                 signal_stat->total_num = 0;
4546                 signal_stat->total_val = 0;
4547                 signal_stat->update_req = 0;
4548         }
4549
4550         signal_stat->total_num++;
4551         signal_stat->total_val  += pattrib->phy_info.SignalQuality;
4552         signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
4553
4554 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4555         if (pattrib->phy_info.SignalQuality != 0) {
4556                 /*  */
4557                 /* 1. Record the general EVM to the sliding window. */
4558                 /*  */
4559                 if (padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) {
4560                         padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
4561                         last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
4562                         padapter->recvpriv.signal_qual_data.total_val -= last_evm;
4563                 }
4564                 padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.SignalQuality;
4565
4566                 padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->phy_info.SignalQuality;
4567                 if (padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
4568                         padapter->recvpriv.signal_qual_data.index = 0;
4569
4570                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Total SQ=%d  pattrib->signal_qual= %d\n", padapter->recvpriv.signal_qual_data.total_val, pattrib->phy_info.SignalQuality));
4571
4572                 /* <1> Showed on UI for user, in percentage. */
4573                 tmpVal = padapter->recvpriv.signal_qual_data.total_val / padapter->recvpriv.signal_qual_data.total_num;
4574                 padapter->recvpriv.signal_qual = (u8)tmpVal;
4575
4576         } else
4577                 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" pattrib->signal_qual =%d\n", pattrib->phy_info.SignalQuality));
4578 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4579 }
4580
4581 void rx_process_phy_info(_adapter *padapter, union recv_frame *rframe)
4582 {
4583         /* Check RSSI */
4584         rx_process_rssi(padapter, rframe);
4585
4586         /* Check PWDB */
4587         /* process_PWDB(padapter, rframe); */
4588
4589         /* UpdateRxSignalStatistics8192C(Adapter, pRfd); */
4590
4591         /* Check EVM */
4592         rx_process_link_qual(padapter, rframe);
4593         rtw_store_phy_info(padapter, rframe);
4594 }
4595
4596 void rx_query_phy_status(
4597         union recv_frame        *precvframe,
4598         u8 *pphy_status)
4599 {
4600         PADAPTER                        padapter = precvframe->u.hdr.adapter;
4601         struct rx_pkt_attrib    *pattrib = &precvframe->u.hdr.attrib;
4602         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(padapter);
4603         PODM_PHY_INFO_T pPHYInfo  = (PODM_PHY_INFO_T)(&pattrib->phy_info);
4604         u8                                      *wlanhdr;
4605         ODM_PACKET_INFO_T       pkt_info;
4606         u8 *sa;
4607         struct sta_priv *pstapriv;
4608         struct sta_info *psta = NULL;
4609         struct dvobj_priv *psdpriv = padapter->dvobj;
4610         struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
4611         /* _irqL                irqL; */
4612
4613         pkt_info.bPacketMatchBSSID = _FALSE;
4614         pkt_info.bPacketToSelf = _FALSE;
4615         pkt_info.bPacketBeacon = _FALSE;
4616
4617         wlanhdr = get_recvframe_data(precvframe);
4618
4619         pkt_info.bPacketMatchBSSID = (!IsFrameTypeCtrl(wlanhdr))
4620                              && (!pattrib->icv_err) && (!pattrib->crc_err)
4621                 && _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN);
4622
4623         pkt_info.bToSelf = (!pattrib->icv_err) && (!pattrib->crc_err)
4624                 && _rtw_memcmp(get_ra(wlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
4625
4626         pkt_info.bPacketToSelf = pkt_info.bPacketMatchBSSID
4627                 && _rtw_memcmp(get_ra(wlanhdr), adapter_mac_addr(padapter), ETH_ALEN);
4628
4629         pkt_info.bPacketBeacon = pkt_info.bPacketMatchBSSID
4630                                  && (GetFrameSubType(wlanhdr) == WIFI_BEACON);
4631
4632         sa = get_ta(wlanhdr);
4633
4634         pkt_info.StationID = 0xFF;
4635
4636         if (_rtw_memcmp(adapter_mac_addr(padapter), sa, ETH_ALEN) == _TRUE) {
4637                 static u32 start_time = 0;
4638
4639 #if 0 /*For debug */
4640                 if (IsFrameTypeCtrl(wlanhdr)) {
4641                         RTW_INFO("-->Control frame: Y\n");
4642                         RTW_INFO("-->pkt_len: %d\n", pattrib->pkt_len);
4643                         RTW_INFO("-->Sub Type = 0x%X\n", GetFrameSubType(wlanhdr));
4644                 }
4645
4646                 /* Dump first 40 bytes of header */
4647                 int i = 0;
4648
4649                 for (i = 0; i < 40; i++)
4650                         RTW_INFO("%d: %X\n", i, *((u8 *)wlanhdr + i));
4651
4652                 RTW_INFO("\n");
4653 #endif
4654
4655                 if ((start_time == 0) || (rtw_get_passing_time_ms(start_time) > 5000)) {
4656                         RTW_PRINT("Warning!!! %s: Confilc mac addr!!\n", __func__);
4657                         start_time = rtw_get_current_time();
4658                 }
4659                 pdbgpriv->dbg_rx_conflic_mac_addr_cnt++;
4660         } else {
4661                 pstapriv = &padapter->stapriv;
4662                 psta = rtw_get_stainfo(pstapriv, sa);
4663                 if (psta)
4664                         pkt_info.StationID = psta->mac_id;
4665         }
4666
4667         pkt_info.DataRate = pattrib->data_rate;
4668
4669         /* _enter_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
4670         ODM_PhyStatusQuery(&pHalData->odmpriv, pPHYInfo, pphy_status, &pkt_info);
4671         if (psta)
4672                 psta->rssi = pattrib->phy_info.RecvSignalPower;
4673         /* _exit_critical_bh(&pHalData->odm_stainfo_lock, &irqL); */
4674
4675         {
4676                 precvframe->u.hdr.psta = NULL;
4677                 if (pkt_info.bPacketMatchBSSID
4678                     && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
4679                    ) {
4680                         if (psta) {
4681                                 precvframe->u.hdr.psta = psta;
4682                                 rx_process_phy_info(padapter, precvframe);
4683                         }
4684                 } else if (pkt_info.bPacketToSelf || pkt_info.bPacketBeacon) {
4685
4686                         if (psta)
4687                                 precvframe->u.hdr.psta = psta;
4688                         rx_process_phy_info(padapter, precvframe);
4689                 }
4690         }
4691 }
4692 /*
4693 * Increase and check if the continual_no_rx_packet of this @param pmlmepriv is larger than MAX_CONTINUAL_NORXPACKET_COUNT
4694 * @return _TRUE:
4695 * @return _FALSE:
4696 */
4697 int rtw_inc_and_chk_continual_no_rx_packet(struct sta_info *sta, int tid_index)
4698 {
4699
4700         int ret = _FALSE;
4701         int value = ATOMIC_INC_RETURN(&sta->continual_no_rx_packet[tid_index]);
4702
4703         if (value >= MAX_CONTINUAL_NORXPACKET_COUNT)
4704                 ret = _TRUE;
4705
4706         return ret;
4707 }
4708
4709 /*
4710 * Set the continual_no_rx_packet of this @param pmlmepriv to 0
4711 */
4712 void rtw_reset_continual_no_rx_packet(struct sta_info *sta, int tid_index)
4713 {
4714         ATOMIC_SET(&sta->continual_no_rx_packet[tid_index], 0);
4715 }
4716
4717
4718 s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status)
4719 {
4720         s32 ret = _SUCCESS;
4721 #ifdef CONFIG_CONCURRENT_MODE
4722         u8 *pda;
4723         u8 *pbuf = precvframe->u.hdr.rx_data;
4724         _adapter *iface = NULL;
4725         _adapter *primary_padapter = precvframe->u.hdr.adapter;
4726
4727         pda = get_ra(pbuf);
4728
4729         if (IS_MCAST(pda) == _FALSE) { /*unicast packets*/
4730                 iface = rtw_get_iface_by_macddr(primary_padapter , pda);
4731                 if (NULL == iface) {
4732                         RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n", __func__, MAC_ARG(pda));
4733                         /*rtw_warn_on(1);*/
4734                 } else
4735                         precvframe->u.hdr.adapter = iface;
4736         } else   /* Handle BC/MC Packets        */
4737                 rtw_mi_buddy_clone_bcmc_packet(primary_padapter, precvframe, pphy_status);
4738 #endif
4739
4740         return ret;
4741 }