1
2
3
4
5
6
7#define _RTW_RECV_C_
8
9#include <drv_types.h>
10#include <rtw_debug.h>
11#include <linux/jiffies.h>
12#include <rtw_recv.h>
13#include <net/cfg80211.h>
14
15static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
16static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
17
18static void rtw_signal_stat_timer_hdl(struct timer_list *t);
19
20void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
21{
22 memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
23
24 spin_lock_init(&psta_recvpriv->lock);
25
26
27
28
29 _rtw_init_queue(&psta_recvpriv->defrag_q);
30}
31
32sint _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
33{
34 sint i;
35 union recv_frame *precvframe;
36 sint res = _SUCCESS;
37
38 spin_lock_init(&precvpriv->lock);
39
40 _rtw_init_queue(&precvpriv->free_recv_queue);
41 _rtw_init_queue(&precvpriv->recv_pending_queue);
42 _rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
43
44 precvpriv->adapter = padapter;
45
46 precvpriv->free_recvframe_cnt = NR_RECVFRAME;
47
48 precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
49
50 if (!precvpriv->pallocated_frame_buf) {
51 res = _FAIL;
52 goto exit;
53 }
54
55 precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
56
57
58
59 precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
60
61
62 for (i = 0; i < NR_RECVFRAME; i++) {
63 INIT_LIST_HEAD(&(precvframe->u.list));
64
65 list_add_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
66
67 rtw_os_recv_resource_alloc(padapter, precvframe);
68
69 precvframe->u.hdr.len = 0;
70
71 precvframe->u.hdr.adapter = padapter;
72 precvframe++;
73
74 }
75
76 res = rtw_hal_init_recv_priv(padapter);
77
78 timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl,
79 0);
80
81 precvpriv->signal_stat_sampling_interval = 2000;
82
83 rtw_set_signal_stat_timer(precvpriv);
84
85exit:
86 return res;
87}
88
89void _rtw_free_recv_priv(struct recv_priv *precvpriv)
90{
91 struct adapter *padapter = precvpriv->adapter;
92
93 rtw_free_uc_swdec_pending_queue(padapter);
94
95 rtw_os_recv_resource_free(precvpriv);
96
97 if (precvpriv->pallocated_frame_buf)
98 vfree(precvpriv->pallocated_frame_buf);
99
100 rtw_hal_free_recv_priv(padapter);
101}
102
103union recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
104{
105
106 union recv_frame *precvframe;
107 struct list_head *plist, *phead;
108 struct adapter *padapter;
109 struct recv_priv *precvpriv;
110
111 if (list_empty(&pfree_recv_queue->queue))
112 precvframe = NULL;
113 else {
114 phead = get_list_head(pfree_recv_queue);
115
116 plist = get_next(phead);
117
118 precvframe = (union recv_frame *)plist;
119
120 list_del_init(&precvframe->u.hdr.list);
121 padapter = precvframe->u.hdr.adapter;
122 if (padapter) {
123 precvpriv = &padapter->recvpriv;
124 if (pfree_recv_queue == &precvpriv->free_recv_queue)
125 precvpriv->free_recvframe_cnt--;
126 }
127 }
128 return precvframe;
129}
130
131union recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
132{
133 union recv_frame *precvframe;
134
135 spin_lock_bh(&pfree_recv_queue->lock);
136
137 precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
138
139 spin_unlock_bh(&pfree_recv_queue->lock);
140
141 return precvframe;
142}
143
144int rtw_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue)
145{
146 struct adapter *padapter = precvframe->u.hdr.adapter;
147 struct recv_priv *precvpriv = &padapter->recvpriv;
148
149 rtw_os_free_recvframe(precvframe);
150
151
152 spin_lock_bh(&pfree_recv_queue->lock);
153
154 list_del_init(&(precvframe->u.hdr.list));
155
156 precvframe->u.hdr.len = 0;
157
158 list_add_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
159
160 if (padapter) {
161 if (pfree_recv_queue == &precvpriv->free_recv_queue)
162 precvpriv->free_recvframe_cnt++;
163 }
164 spin_unlock_bh(&pfree_recv_queue->lock);
165 return _SUCCESS;
166}
167
168
169
170
171sint _rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue)
172{
173
174 struct adapter *padapter = precvframe->u.hdr.adapter;
175 struct recv_priv *precvpriv = &padapter->recvpriv;
176
177
178 list_del_init(&(precvframe->u.hdr.list));
179
180
181 list_add_tail(&(precvframe->u.hdr.list), get_list_head(queue));
182
183 if (padapter)
184 if (queue == &precvpriv->free_recv_queue)
185 precvpriv->free_recvframe_cnt++;
186
187 return _SUCCESS;
188}
189
190sint rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue)
191{
192 sint ret;
193
194
195 spin_lock_bh(&queue->lock);
196 ret = _rtw_enqueue_recvframe(precvframe, queue);
197
198 spin_unlock_bh(&queue->lock);
199
200 return ret;
201}
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221void rtw_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue)
222{
223 union recv_frame *precvframe;
224 struct list_head *plist, *phead;
225
226 spin_lock(&pframequeue->lock);
227
228 phead = get_list_head(pframequeue);
229 plist = get_next(phead);
230
231 while (phead != plist) {
232 precvframe = (union recv_frame *)plist;
233
234 plist = get_next(plist);
235
236 rtw_free_recvframe(precvframe, pfree_recv_queue);
237 }
238
239 spin_unlock(&pframequeue->lock);
240}
241
242u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter)
243{
244 u32 cnt = 0;
245 union recv_frame *pending_frame;
246 while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
247 rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
248 cnt++;
249 }
250
251 if (cnt)
252 DBG_871X(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt);
253
254 return cnt;
255}
256
257
258sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue)
259{
260 spin_lock_bh(&queue->lock);
261
262 list_del_init(&precvbuf->list);
263 list_add(&precvbuf->list, get_list_head(queue));
264
265 spin_unlock_bh(&queue->lock);
266
267 return _SUCCESS;
268}
269
270sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue)
271{
272 spin_lock_bh(&queue->lock);
273
274 list_del_init(&precvbuf->list);
275
276 list_add_tail(&precvbuf->list, get_list_head(queue));
277 spin_unlock_bh(&queue->lock);
278 return _SUCCESS;
279
280}
281
282struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue)
283{
284 struct recv_buf *precvbuf;
285 struct list_head *plist, *phead;
286
287 spin_lock_bh(&queue->lock);
288
289 if (list_empty(&queue->queue))
290 precvbuf = NULL;
291 else {
292 phead = get_list_head(queue);
293
294 plist = get_next(phead);
295
296 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
297
298 list_del_init(&precvbuf->list);
299
300 }
301
302 spin_unlock_bh(&queue->lock);
303
304 return precvbuf;
305
306}
307
308sint recvframe_chkmic(struct adapter *adapter, union recv_frame *precvframe);
309sint recvframe_chkmic(struct adapter *adapter, union recv_frame *precvframe)
310{
311
312 sint i, res = _SUCCESS;
313 u32 datalen;
314 u8 miccode[8];
315 u8 bmic_err = false, brpt_micerror = true;
316 u8 *pframe, *payload, *pframemic;
317 u8 *mickey;
318
319 struct sta_info *stainfo;
320 struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib;
321 struct security_priv *psecuritypriv = &adapter->securitypriv;
322
323 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
324 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
325
326 stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
327
328 if (prxattrib->encrypt == _TKIP_) {
329 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic:prxattrib->encrypt == _TKIP_\n"));
330 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",
331 prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2], prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5]));
332
333
334 if (stainfo) {
335 if (IS_MCAST(prxattrib->ra)) {
336
337
338
339 mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
340
341 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic: bcmc key\n"));
342
343
344
345 if (psecuritypriv->binstallGrpkey == false) {
346 res = _FAIL;
347 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"));
348 DBG_871X("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
349 goto exit;
350 }
351 } else {
352 mickey = &stainfo->dot11tkiprxmickey.skey[0];
353 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic: unicast key\n"));
354 }
355
356 datalen = precvframe->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len-prxattrib->icv_len-8;
357 pframe = precvframe->u.hdr.rx_data;
358 payload = pframe+prxattrib->hdrlen+prxattrib->iv_len;
359
360 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n prxattrib->iv_len =%d prxattrib->icv_len =%d\n", prxattrib->iv_len, prxattrib->icv_len));
361
362
363 rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0], (unsigned char)prxattrib->priority);
364
365 pframemic = payload+datalen;
366
367 bmic_err = false;
368
369 for (i = 0; i < 8; i++) {
370 if (miccode[i] != *(pframemic+i)) {
371 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ", i, miccode[i], i, *(pframemic+i)));
372 bmic_err = true;
373 }
374 }
375
376
377 if (bmic_err == true) {
378
379 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",
380 *(pframemic-8), *(pframemic-7), *(pframemic-6), *(pframemic-5), *(pframemic-4), *(pframemic-3), *(pframemic-2), *(pframemic-1)));
381 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",
382 *(pframemic-16), *(pframemic-15), *(pframemic-14), *(pframemic-13), *(pframemic-12), *(pframemic-11), *(pframemic-10), *(pframemic-9)));
383
384 {
385 uint i;
386 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet (len =%d) ======\n", precvframe->u.hdr.len));
387 for (i = 0; i < precvframe->u.hdr.len; i = i+8) {
388 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x",
389 *(precvframe->u.hdr.rx_data+i), *(precvframe->u.hdr.rx_data+i+1),
390 *(precvframe->u.hdr.rx_data+i+2), *(precvframe->u.hdr.rx_data+i+3),
391 *(precvframe->u.hdr.rx_data+i+4), *(precvframe->u.hdr.rx_data+i+5),
392 *(precvframe->u.hdr.rx_data+i+6), *(precvframe->u.hdr.rx_data+i+7)));
393 }
394 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet end [len =%d]======\n", precvframe->u.hdr.len));
395 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n hrdlen =%d,\n", prxattrib->hdrlen));
396 }
397
398 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ra = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey =%d ",
399 prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2],
400 prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5], psecuritypriv->binstallGrpkey));
401
402
403
404 if ((IS_MCAST(prxattrib->ra) == true) && (prxattrib->key_index != pmlmeinfo->key_index))
405 brpt_micerror = false;
406
407 if ((prxattrib->bdecrypted == true) && (brpt_micerror == true)) {
408 rtw_handle_tkip_mic_err(adapter, (u8)IS_MCAST(prxattrib->ra));
409 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted));
410 DBG_871X(" mic error :prxattrib->bdecrypted =%d\n", prxattrib->bdecrypted);
411 } else {
412 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted));
413 DBG_871X(" mic error :prxattrib->bdecrypted =%d\n", prxattrib->bdecrypted);
414 }
415
416 res = _FAIL;
417
418 } else {
419
420 if ((psecuritypriv->bcheck_grpkey == false) && (IS_MCAST(prxattrib->ra) == true)) {
421 psecuritypriv->bcheck_grpkey = true;
422 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("psecuritypriv->bcheck_grpkey =true"));
423 }
424 }
425
426 } else
427 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic: rtw_get_stainfo == NULL!!!\n"));
428
429 recvframe_pull_tail(precvframe, 8);
430
431 }
432
433exit:
434 return res;
435
436}
437
438
439union recv_frame *decryptor(struct adapter *padapter, union recv_frame *precv_frame);
440union recv_frame *decryptor(struct adapter *padapter, union recv_frame *precv_frame)
441{
442
443 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
444 struct security_priv *psecuritypriv = &padapter->securitypriv;
445 union recv_frame *return_packet = precv_frame;
446 u32 res = _SUCCESS;
447
448 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt);
449
450 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n", prxattrib->bdecrypted, prxattrib->encrypt));
451
452 if (prxattrib->encrypt > 0) {
453 u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen;
454 prxattrib->key_index = (((iv[3])>>6)&0x3);
455
456 if (prxattrib->key_index > WEP_KEYS) {
457 DBG_871X("prxattrib->key_index(%d) > WEP_KEYS\n", prxattrib->key_index);
458
459 switch (prxattrib->encrypt) {
460 case _WEP40_:
461 case _WEP104_:
462 prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
463 break;
464 case _TKIP_:
465 case _AES_:
466 default:
467 prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
468 break;
469 }
470 }
471 }
472
473 if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt == true))) {
474 psecuritypriv->hw_decrypted = false;
475
476 #ifdef DBG_RX_DECRYPTOR
477 DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
478 __func__,
479 __LINE__,
480 prxattrib->bdecrypted,
481 prxattrib->encrypt,
482 psecuritypriv->hw_decrypted);
483 #endif
484
485 switch (prxattrib->encrypt) {
486 case _WEP40_:
487 case _WEP104_:
488 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep);
489 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
490 break;
491 case _TKIP_:
492 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip);
493 res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
494 break;
495 case _AES_:
496 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes);
497 res = rtw_aes_decrypt(padapter, (u8 *)precv_frame);
498 break;
499 default:
500 break;
501 }
502 } else if (prxattrib->bdecrypted == 1
503 && prxattrib->encrypt > 0
504 && (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)
505 ) {
506 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw);
507
508 psecuritypriv->hw_decrypted = true;
509 #ifdef DBG_RX_DECRYPTOR
510 DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
511 __func__,
512 __LINE__,
513 prxattrib->bdecrypted,
514 prxattrib->encrypt,
515 psecuritypriv->hw_decrypted);
516
517 #endif
518 } else {
519 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown);
520 #ifdef DBG_RX_DECRYPTOR
521 DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
522 __func__,
523 __LINE__,
524 prxattrib->bdecrypted,
525 prxattrib->encrypt,
526 psecuritypriv->hw_decrypted);
527 #endif
528 }
529
530 if (res == _FAIL) {
531 rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
532 return_packet = NULL;
533 } else
534 prxattrib->bdecrypted = true;
535
536 return return_packet;
537}
538
539
540union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame);
541union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame)
542{
543 u8 *psta_addr = NULL;
544 u8 *ptr;
545 uint auth_alg;
546 struct recv_frame_hdr *pfhdr;
547 struct sta_info *psta;
548 struct sta_priv *pstapriv;
549 union recv_frame *prtnframe;
550 u16 ether_type = 0;
551 u16 eapol_type = 0x888e;
552 struct rx_pkt_attrib *pattrib;
553
554 pstapriv = &adapter->stapriv;
555
556 auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
557
558 ptr = get_recvframe_data(precv_frame);
559 pfhdr = &precv_frame->u.hdr;
560 pattrib = &pfhdr->attrib;
561 psta_addr = pattrib->ta;
562
563 prtnframe = NULL;
564
565 psta = rtw_get_stainfo(pstapriv, psta_addr);
566
567 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm =%d\n", adapter->securitypriv.dot11AuthAlgrthm));
568
569 if (auth_alg == 2) {
570 if ((psta) && (psta->ieee8021x_blocked)) {
571 __be16 be_tmp;
572
573
574
575 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked == 1\n"));
576
577 prtnframe = precv_frame;
578
579
580 ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
581 memcpy(&be_tmp, ptr, 2);
582 ether_type = ntohs(be_tmp);
583
584 if (ether_type == eapol_type)
585 prtnframe = precv_frame;
586 else {
587
588 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
589 prtnframe = NULL;
590 }
591 } else {
592
593
594 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked == 0\n"));
595 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:precv_frame->hdr.attrib.privacy =%x\n", precv_frame->u.hdr.attrib.privacy));
596
597 if (pattrib->bdecrypted == 0)
598 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:prxstat->decrypted =%x\n", pattrib->bdecrypted));
599
600 prtnframe = precv_frame;
601
602
603
604
605
606
607
608
609
610
611 }
612 } else
613 prtnframe = precv_frame;
614
615 return prtnframe;
616}
617
618sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache);
619sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache)
620{
621 sint tid = precv_frame->u.hdr.attrib.priority;
622
623 u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
624 (precv_frame->u.hdr.attrib.frag_num & 0xf);
625
626 if (tid > 15) {
627 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n", seq_ctrl, tid));
628
629 return _FAIL;
630 }
631
632 if (1) {
633 if (seq_ctrl == prxcache->tid_rxseq[tid]) {
634 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]));
635
636 return _FAIL;
637 }
638 }
639
640 prxcache->tid_rxseq[tid] = seq_ctrl;
641
642 return _SUCCESS;
643
644}
645
646void process_pwrbit_data(struct adapter *padapter, union recv_frame *precv_frame);
647void process_pwrbit_data(struct adapter *padapter, union recv_frame *precv_frame)
648{
649 unsigned char pwrbit;
650 u8 *ptr = precv_frame->u.hdr.rx_data;
651 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
652 struct sta_priv *pstapriv = &padapter->stapriv;
653 struct sta_info *psta = NULL;
654
655 psta = rtw_get_stainfo(pstapriv, pattrib->src);
656
657 pwrbit = GetPwrMgt(ptr);
658
659 if (psta) {
660 if (pwrbit) {
661 if (!(psta->state & WIFI_SLEEP_STATE)) {
662
663
664
665 stop_sta_xmit(padapter, psta);
666
667
668 }
669 } else {
670 if (psta->state & WIFI_SLEEP_STATE) {
671
672
673
674 wakeup_sta_to_xmit(padapter, psta);
675
676
677 }
678 }
679
680 }
681}
682
683void process_wmmps_data(struct adapter *padapter, union recv_frame *precv_frame);
684void process_wmmps_data(struct adapter *padapter, union recv_frame *precv_frame)
685{
686 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
687 struct sta_priv *pstapriv = &padapter->stapriv;
688 struct sta_info *psta = NULL;
689
690 psta = rtw_get_stainfo(pstapriv, pattrib->src);
691
692 if (!psta)
693 return;
694
695 if (!psta->qos_option)
696 return;
697
698 if (!(psta->qos_info&0xf))
699 return;
700
701 if (psta->state&WIFI_SLEEP_STATE) {
702 u8 wmmps_ac = 0;
703
704 switch (pattrib->priority) {
705 case 1:
706 case 2:
707 wmmps_ac = psta->uapsd_bk&BIT(1);
708 break;
709 case 4:
710 case 5:
711 wmmps_ac = psta->uapsd_vi&BIT(1);
712 break;
713 case 6:
714 case 7:
715 wmmps_ac = psta->uapsd_vo&BIT(1);
716 break;
717 case 0:
718 case 3:
719 default:
720 wmmps_ac = psta->uapsd_be&BIT(1);
721 break;
722 }
723
724 if (wmmps_ac) {
725 if (psta->sleepq_ac_len > 0)
726
727 xmit_delivery_enabled_frames(padapter, psta);
728 else
729
730 issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0);
731 }
732 }
733}
734
735void count_rx_stats(struct adapter *padapter, union recv_frame *prframe, struct sta_info *sta);
736void count_rx_stats(struct adapter *padapter, union recv_frame *prframe, struct sta_info *sta)
737{
738 int sz;
739 struct sta_info *psta = NULL;
740 struct stainfo_stats *pstats = NULL;
741 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
742 struct recv_priv *precvpriv = &padapter->recvpriv;
743
744 sz = get_recvframe_len(prframe);
745 precvpriv->rx_bytes += sz;
746
747 padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
748
749 if ((!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))) {
750 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
751 }
752
753 if (sta)
754 psta = sta;
755 else
756 psta = prframe->u.hdr.psta;
757
758 if (psta) {
759 pstats = &psta->sta_stats;
760
761 pstats->rx_data_pkts++;
762 pstats->rx_bytes += sz;
763 }
764
765 traffic_check_for_leave_lps(padapter, false, 0);
766}
767
768sint sta2sta_data_frame(
769 struct adapter *adapter,
770 union recv_frame *precv_frame,
771 struct sta_info **psta
772);
773sint sta2sta_data_frame(
774 struct adapter *adapter,
775 union recv_frame *precv_frame,
776 struct sta_info **psta
777)
778{
779 u8 *ptr = precv_frame->u.hdr.rx_data;
780 sint ret = _SUCCESS;
781 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
782 struct sta_priv *pstapriv = &adapter->stapriv;
783 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
784 u8 *mybssid = get_bssid(pmlmepriv);
785 u8 *myhwaddr = myid(&adapter->eeprompriv);
786 u8 *sta_addr = NULL;
787 sint bmcast = IS_MCAST(pattrib->dst);
788
789
790
791 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
792 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
793
794
795 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
796 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA ==myself\n"));
797 ret = _FAIL;
798 goto exit;
799 }
800
801 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
802 ret = _FAIL;
803 goto exit;
804 }
805
806 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
807 !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
808 (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
809 ret = _FAIL;
810 goto exit;
811 }
812
813 sta_addr = pattrib->src;
814
815 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) {
816
817 if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
818 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("bssid != TA under STATION_MODE; drop pkt\n"));
819 ret = _FAIL;
820 goto exit;
821 }
822
823 sta_addr = pattrib->bssid;
824 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
825 if (bmcast) {
826
827 if (!IS_MCAST(pattrib->bssid)) {
828 ret = _FAIL;
829 goto exit;
830 }
831 } else {
832
833 if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
834 ret = _FAIL;
835 goto exit;
836 }
837
838 sta_addr = pattrib->src;
839 }
840
841 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
842 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
843 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
844 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
845 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
846 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
847
848 sta_addr = mybssid;
849 } else
850 ret = _FAIL;
851
852
853
854 if (bmcast)
855 *psta = rtw_get_bcmc_stainfo(adapter);
856 else
857 *psta = rtw_get_stainfo(pstapriv, sta_addr);
858
859 if (!*psta) {
860 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under sta2sta_data_frame ; drop pkt\n"));
861 ret = _FAIL;
862 goto exit;
863 }
864
865exit:
866 return ret;
867}
868
869sint ap2sta_data_frame(
870 struct adapter *adapter,
871 union recv_frame *precv_frame,
872 struct sta_info **psta);
873sint ap2sta_data_frame(
874 struct adapter *adapter,
875 union recv_frame *precv_frame,
876 struct sta_info **psta)
877{
878 u8 *ptr = precv_frame->u.hdr.rx_data;
879 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
880 sint ret = _SUCCESS;
881 struct sta_priv *pstapriv = &adapter->stapriv;
882 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
883 u8 *mybssid = get_bssid(pmlmepriv);
884 u8 *myhwaddr = myid(&adapter->eeprompriv);
885 sint bmcast = IS_MCAST(pattrib->dst);
886
887 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)
888 && (check_fwstate(pmlmepriv, _FW_LINKED) == true
889 || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true)
890 ) {
891
892
893 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
894 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA ==myself\n"));
895 #ifdef DBG_RX_DROP_FRAME
896 DBG_871X("DBG_RX_DROP_FRAME %s SA ="MAC_FMT", myhwaddr ="MAC_FMT"\n",
897 __func__, MAC_ARG(pattrib->src), MAC_ARG(myhwaddr));
898 #endif
899 ret = _FAIL;
900 goto exit;
901 }
902
903
904 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
905 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
906 (" ap2sta_data_frame: compare DA fail; DA ="MAC_FMT"\n", MAC_ARG(pattrib->dst)));
907 #ifdef DBG_RX_DROP_FRAME
908 DBG_871X("DBG_RX_DROP_FRAME %s DA ="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst));
909 #endif
910 ret = _FAIL;
911 goto exit;
912 }
913
914
915
916 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
917 !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
918 (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
919 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
920 (" ap2sta_data_frame: compare BSSID fail ; BSSID ="MAC_FMT"\n", MAC_ARG(pattrib->bssid)));
921 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("mybssid ="MAC_FMT"\n", MAC_ARG(mybssid)));
922 #ifdef DBG_RX_DROP_FRAME
923 DBG_871X("DBG_RX_DROP_FRAME %s BSSID ="MAC_FMT", mybssid ="MAC_FMT"\n",
924 __func__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
925 DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct adapter->adapter_type);
926 #endif
927
928 if (!bmcast) {
929 DBG_871X("issue_deauth to the nonassociated ap =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
930 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
931 }
932
933 ret = _FAIL;
934 goto exit;
935 }
936
937 if (bmcast)
938 *psta = rtw_get_bcmc_stainfo(adapter);
939 else
940 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid);
941
942 if (!*psta) {
943 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ap2sta: can't get psta under STATION_MODE ; drop pkt\n"));
944 #ifdef DBG_RX_DROP_FRAME
945 DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __func__);
946 #endif
947 ret = _FAIL;
948 goto exit;
949 }
950
951 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
952 }
953
954 if (GetFrameSubType(ptr) & BIT(6)) {
955
956 count_rx_stats(adapter, precv_frame, *psta);
957 ret = RTW_RX_HANDLED;
958 goto exit;
959 }
960
961 } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) &&
962 (check_fwstate(pmlmepriv, _FW_LINKED) == true)) {
963 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
964 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
965 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
966 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
967 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
968
969
970 memcpy(pattrib->bssid, mybssid, ETH_ALEN);
971
972
973 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid);
974 if (!*psta) {
975 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n"));
976 #ifdef DBG_RX_DROP_FRAME
977 DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __func__);
978 #endif
979 ret = _FAIL;
980 goto exit;
981 }
982
983
984 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
985
986 ret = RTW_RX_HANDLED;
987 goto exit;
988 } else {
989 if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
990 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid);
991 if (!*psta) {
992
993
994 static unsigned long send_issue_deauth_time;
995
996
997
998 if (jiffies_to_msecs(jiffies - send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) {
999 send_issue_deauth_time = jiffies;
1000
1001 DBG_871X("issue_deauth to the ap =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1002
1003 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1004 }
1005 }
1006 }
1007
1008 ret = _FAIL;
1009 #ifdef DBG_RX_DROP_FRAME
1010 DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __func__, get_fwstate(pmlmepriv));
1011 #endif
1012 }
1013
1014exit:
1015 return ret;
1016}
1017
1018sint sta2ap_data_frame(
1019 struct adapter *adapter,
1020 union recv_frame *precv_frame,
1021 struct sta_info **psta);
1022sint sta2ap_data_frame(
1023 struct adapter *adapter,
1024 union recv_frame *precv_frame,
1025 struct sta_info **psta)
1026{
1027 u8 *ptr = precv_frame->u.hdr.rx_data;
1028 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1029 struct sta_priv *pstapriv = &adapter->stapriv;
1030 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1031 unsigned char *mybssid = get_bssid(pmlmepriv);
1032 sint ret = _SUCCESS;
1033
1034 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
1035
1036 if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1037 ret = _FAIL;
1038 goto exit;
1039 }
1040
1041 *psta = rtw_get_stainfo(pstapriv, pattrib->src);
1042 if (!*psta) {
1043 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under AP_MODE; drop pkt\n"));
1044 DBG_871X("issue_deauth to sta =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1045
1046 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1047
1048 ret = RTW_RX_HANDLED;
1049 goto exit;
1050 }
1051
1052 process_pwrbit_data(adapter, precv_frame);
1053
1054 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1055 process_wmmps_data(adapter, precv_frame);
1056 }
1057
1058 if (GetFrameSubType(ptr) & BIT(6)) {
1059
1060 count_rx_stats(adapter, precv_frame, *psta);
1061 ret = RTW_RX_HANDLED;
1062 goto exit;
1063 }
1064 } else {
1065 u8 *myhwaddr = myid(&adapter->eeprompriv);
1066 if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1067 ret = RTW_RX_HANDLED;
1068 goto exit;
1069 }
1070 DBG_871X("issue_deauth to sta =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1071 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1072 ret = RTW_RX_HANDLED;
1073 goto exit;
1074 }
1075
1076exit:
1077 return ret;
1078}
1079
1080sint validate_recv_ctrl_frame(struct adapter *padapter, union recv_frame *precv_frame);
1081sint validate_recv_ctrl_frame(struct adapter *padapter, union recv_frame *precv_frame)
1082{
1083 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1084 struct sta_priv *pstapriv = &padapter->stapriv;
1085 u8 *pframe = precv_frame->u.hdr.rx_data;
1086 struct sta_info *psta = NULL;
1087
1088
1089
1090
1091 if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1092 return _FAIL;
1093
1094
1095 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN))
1096 return _FAIL;
1097
1098 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1099 if (!psta)
1100 return _FAIL;
1101
1102
1103 psta->sta_stats.rx_ctrl_pkts++;
1104
1105
1106 if (GetFrameSubType(pframe) == WIFI_PSPOLL) {
1107 u16 aid;
1108 u8 wmmps_ac = 0;
1109
1110 aid = GetAid(pframe);
1111 if (psta->aid != aid)
1112 return _FAIL;
1113
1114 switch (pattrib->priority) {
1115 case 1:
1116 case 2:
1117 wmmps_ac = psta->uapsd_bk&BIT(0);
1118 break;
1119 case 4:
1120 case 5:
1121 wmmps_ac = psta->uapsd_vi&BIT(0);
1122 break;
1123 case 6:
1124 case 7:
1125 wmmps_ac = psta->uapsd_vo&BIT(0);
1126 break;
1127 case 0:
1128 case 3:
1129 default:
1130 wmmps_ac = psta->uapsd_be&BIT(0);
1131 break;
1132 }
1133
1134 if (wmmps_ac)
1135 return _FAIL;
1136
1137 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1138 DBG_871X("%s alive check-rx ps-poll\n", __func__);
1139 psta->expire_to = pstapriv->expire_to;
1140 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1141 }
1142
1143 if ((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) {
1144 struct list_head *xmitframe_plist, *xmitframe_phead;
1145 struct xmit_frame *pxmitframe = NULL;
1146 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1147
1148
1149 spin_lock_bh(&pxmitpriv->lock);
1150
1151 xmitframe_phead = get_list_head(&psta->sleep_q);
1152 xmitframe_plist = get_next(xmitframe_phead);
1153
1154 if (xmitframe_phead != xmitframe_plist) {
1155 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1156
1157 xmitframe_plist = get_next(xmitframe_plist);
1158
1159 list_del_init(&pxmitframe->list);
1160
1161 psta->sleepq_len--;
1162
1163 if (psta->sleepq_len > 0)
1164 pxmitframe->attrib.mdata = 1;
1165 else
1166 pxmitframe->attrib.mdata = 0;
1167
1168 pxmitframe->attrib.triggered = 1;
1169
1170
1171
1172 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1173
1174 if (psta->sleepq_len == 0) {
1175 pstapriv->tim_bitmap &= ~BIT(psta->aid);
1176
1177
1178
1179
1180
1181 update_beacon(padapter, _TIM_IE_, NULL, true);
1182 }
1183
1184
1185 spin_unlock_bh(&pxmitpriv->lock);
1186
1187 } else {
1188
1189 spin_unlock_bh(&pxmitpriv->lock);
1190
1191
1192 if (pstapriv->tim_bitmap&BIT(psta->aid)) {
1193 if (psta->sleepq_len == 0) {
1194 DBG_871X("no buffered packets to xmit\n");
1195
1196
1197 issue_nulldata_in_interrupt(padapter, psta->hwaddr);
1198 } else {
1199 DBG_871X("error!psta->sleepq_len =%d\n", psta->sleepq_len);
1200 psta->sleepq_len = 0;
1201 }
1202
1203 pstapriv->tim_bitmap &= ~BIT(psta->aid);
1204
1205
1206
1207 update_beacon(padapter, _TIM_IE_, NULL, true);
1208 }
1209 }
1210 }
1211 }
1212
1213 return _FAIL;
1214
1215}
1216
1217union recv_frame *recvframe_chk_defrag(struct adapter *padapter, union recv_frame *precv_frame);
1218sint validate_recv_mgnt_frame(struct adapter *padapter, union recv_frame *precv_frame);
1219sint validate_recv_mgnt_frame(struct adapter *padapter, union recv_frame *precv_frame)
1220{
1221
1222
1223 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n"));
1224
1225 precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1226 if (!precv_frame) {
1227 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("%s: fragment packet\n", __func__));
1228 return _SUCCESS;
1229 }
1230
1231 {
1232
1233 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data));
1234 if (psta) {
1235 psta->sta_stats.rx_mgnt_pkts++;
1236 if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON)
1237 psta->sta_stats.rx_beacon_pkts++;
1238 else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ)
1239 psta->sta_stats.rx_probereq_pkts++;
1240 else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
1241 if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN))
1242 psta->sta_stats.rx_probersp_pkts++;
1243 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))
1244 || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
1245 psta->sta_stats.rx_probersp_bm_pkts++;
1246 else
1247 psta->sta_stats.rx_probersp_uo_pkts++;
1248 }
1249 }
1250 }
1251
1252 mgt_dispatcher(padapter, precv_frame);
1253
1254 return _SUCCESS;
1255
1256}
1257
1258sint validate_recv_data_frame(struct adapter *adapter, union recv_frame *precv_frame);
1259sint validate_recv_data_frame(struct adapter *adapter, union recv_frame *precv_frame)
1260{
1261 u8 bretry;
1262 u8 *psa, *pda, *pbssid;
1263 struct sta_info *psta = NULL;
1264 u8 *ptr = precv_frame->u.hdr.rx_data;
1265 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1266 struct security_priv *psecuritypriv = &adapter->securitypriv;
1267 sint ret = _SUCCESS;
1268
1269 bretry = GetRetry(ptr);
1270 pda = get_da(ptr);
1271 psa = get_sa(ptr);
1272 pbssid = get_hdr_bssid(ptr);
1273
1274 if (!pbssid) {
1275 #ifdef DBG_RX_DROP_FRAME
1276 DBG_871X("DBG_RX_DROP_FRAME %s pbssid == NULL\n", __func__);
1277 #endif
1278 ret = _FAIL;
1279 goto exit;
1280 }
1281
1282 memcpy(pattrib->dst, pda, ETH_ALEN);
1283 memcpy(pattrib->src, psa, ETH_ALEN);
1284
1285 memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1286
1287 switch (pattrib->to_fr_ds) {
1288 case 0:
1289 memcpy(pattrib->ra, pda, ETH_ALEN);
1290 memcpy(pattrib->ta, psa, ETH_ALEN);
1291 ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1292 break;
1293
1294 case 1:
1295 memcpy(pattrib->ra, pda, ETH_ALEN);
1296 memcpy(pattrib->ta, pbssid, ETH_ALEN);
1297 ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1298 break;
1299
1300 case 2:
1301 memcpy(pattrib->ra, pbssid, ETH_ALEN);
1302 memcpy(pattrib->ta, psa, ETH_ALEN);
1303 ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1304 break;
1305
1306 case 3:
1307 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1308 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1309 ret = _FAIL;
1310 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n"));
1311 break;
1312
1313 default:
1314 ret = _FAIL;
1315 break;
1316
1317 }
1318
1319 if (ret == _FAIL) {
1320 #ifdef DBG_RX_DROP_FRAME
1321 DBG_871X("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __func__, pattrib->to_fr_ds, ret);
1322 #endif
1323 goto exit;
1324 } else if (ret == RTW_RX_HANDLED) {
1325 goto exit;
1326 }
1327
1328
1329 if (!psta) {
1330 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" after to_fr_ds_chk; psta == NULL\n"));
1331 #ifdef DBG_RX_DROP_FRAME
1332 DBG_871X("DBG_RX_DROP_FRAME %s psta == NULL\n", __func__);
1333 #endif
1334 ret = _FAIL;
1335 goto exit;
1336 }
1337
1338
1339
1340 precv_frame->u.hdr.psta = psta;
1341
1342
1343 pattrib->amsdu = 0;
1344 pattrib->ack_policy = 0;
1345
1346 if (pattrib->qos == 1) {
1347 pattrib->priority = GetPriority((ptr + 24));
1348 pattrib->ack_policy = GetAckpolicy((ptr + 24));
1349 pattrib->amsdu = GetAMsdu((ptr + 24));
1350 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
1351
1352 if (pattrib->priority != 0 && pattrib->priority != 3)
1353 adapter->recvpriv.bIsAnyNonBEPkts = true;
1354
1355 } else {
1356 pattrib->priority = 0;
1357 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24;
1358 }
1359
1360
1361 if (pattrib->order)
1362 pattrib->hdrlen += 4;
1363
1364 precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1365
1366
1367 if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) {
1368 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decache : drop pkt\n"));
1369 #ifdef DBG_RX_DROP_FRAME
1370 DBG_871X("DBG_RX_DROP_FRAME %s recv_decache return _FAIL\n", __func__);
1371 #endif
1372 ret = _FAIL;
1373 goto exit;
1374 }
1375
1376 if (pattrib->privacy) {
1377
1378 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("validate_recv_data_frame:pattrib->privacy =%x\n", pattrib->privacy));
1379 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)));
1380
1381 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
1382
1383 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt =%d\n", pattrib->encrypt));
1384
1385 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1386 } else {
1387 pattrib->encrypt = 0;
1388 pattrib->iv_len = pattrib->icv_len = 0;
1389 }
1390
1391exit:
1392 return ret;
1393}
1394
1395static sint validate_80211w_mgmt(struct adapter *adapter, union recv_frame *precv_frame)
1396{
1397 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1398 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1399 u8 *ptr = precv_frame->u.hdr.rx_data;
1400 u8 subtype;
1401
1402 subtype = GetFrameSubType(ptr);
1403
1404
1405 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)
1406 && adapter->securitypriv.binstallBIPkey == true) {
1407
1408 if (pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) &&
1409 (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION)) {
1410 u8 *mgmt_DATA;
1411 u32 data_len = 0;
1412
1413 pattrib->bdecrypted = 0;
1414 pattrib->encrypt = _AES_;
1415 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
1416
1417 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1418 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1419 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1420
1421 data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
1422 mgmt_DATA = rtw_zmalloc(data_len);
1423 if (!mgmt_DATA) {
1424 DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __func__);
1425 goto validate_80211w_fail;
1426 }
1427 precv_frame = decryptor(adapter, precv_frame);
1428
1429 memcpy(mgmt_DATA, ptr+pattrib->hdrlen+pattrib->iv_len, data_len);
1430
1431 memcpy(ptr+pattrib->hdrlen, mgmt_DATA, data_len);
1432
1433 pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len;
1434 kfree(mgmt_DATA);
1435 if (!precv_frame) {
1436 DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __func__);
1437 goto validate_80211w_fail;
1438 }
1439 } else if (IS_MCAST(GetAddr1Ptr(ptr)) &&
1440 (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)) {
1441 sint BIP_ret = _SUCCESS;
1442
1443 BIP_ret = rtw_BIP_verify(adapter, (u8 *)precv_frame);
1444 if (BIP_ret == _FAIL) {
1445
1446 goto validate_80211w_fail;
1447 } else if (BIP_ret == RTW_RX_HANDLED) {
1448
1449
1450 issue_action_SA_Query(adapter, NULL, 0, 0);
1451 goto validate_80211w_fail;
1452 }
1453 } else {
1454 if (subtype == WIFI_ACTION) {
1455
1456 if (ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC &&
1457 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT &&
1458 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM &&
1459 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED &&
1460 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P) {
1461 DBG_871X("action frame category =%d should robust\n", ptr[WLAN_HDR_A3_LEN]);
1462 goto validate_80211w_fail;
1463 }
1464 } else if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
1465 DBG_871X("802.11w recv none protected packet\n");
1466
1467 issue_action_SA_Query(adapter, NULL, 0, 0);
1468 goto validate_80211w_fail;
1469 }
1470 }
1471 }
1472 return _SUCCESS;
1473
1474validate_80211w_fail:
1475 return _FAIL;
1476
1477}
1478
1479static inline void dump_rx_packet(u8 *ptr)
1480{
1481 int i;
1482
1483 DBG_871X("#############################\n");
1484 for (i = 0; i < 64; i = i+8)
1485 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i),
1486 *(ptr+i+1), *(ptr+i+2), *(ptr+i+3), *(ptr+i+4), *(ptr+i+5), *(ptr+i+6), *(ptr+i+7));
1487 DBG_871X("#############################\n");
1488}
1489
1490sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame);
1491sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame)
1492{
1493
1494
1495
1496
1497 u8 type;
1498 u8 subtype;
1499 sint retval = _SUCCESS;
1500 u8 bDumpRxPkt;
1501
1502 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1503
1504 u8 *ptr = precv_frame->u.hdr.rx_data;
1505 u8 ver = (unsigned char) (*ptr)&0x3;
1506
1507
1508 if (ver != 0) {
1509 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! (ver!= 0)\n"));
1510 retval = _FAIL;
1511 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err);
1512 goto exit;
1513 }
1514
1515 type = GetFrameType(ptr);
1516 subtype = GetFrameSubType(ptr);
1517
1518 pattrib->to_fr_ds = get_tofr_ds(ptr);
1519
1520 pattrib->frag_num = GetFragNum(ptr);
1521 pattrib->seq_num = GetSequence(ptr);
1522
1523 pattrib->pw_save = GetPwrMgt(ptr);
1524 pattrib->mfrag = GetMFrag(ptr);
1525 pattrib->mdata = GetMData(ptr);
1526 pattrib->privacy = GetPrivacy(ptr);
1527 pattrib->order = GetOrder(ptr);
1528 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
1529 if (bDumpRxPkt == 1)
1530 dump_rx_packet(ptr);
1531 else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE))
1532 dump_rx_packet(ptr);
1533 else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE))
1534 dump_rx_packet(ptr);
1535
1536 switch (type) {
1537 case WIFI_MGT_TYPE:
1538 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt);
1539 if (validate_80211w_mgmt(adapter, precv_frame) == _FAIL) {
1540 retval = _FAIL;
1541 DBG_COUNTER(padapter->rx_logs.core_rx_pre_mgmt_err_80211w);
1542 break;
1543 }
1544
1545 retval = validate_recv_mgnt_frame(adapter, precv_frame);
1546 if (retval == _FAIL) {
1547 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_mgnt_frame fail\n"));
1548 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err);
1549 }
1550 retval = _FAIL;
1551 break;
1552 case WIFI_CTRL_TYPE:
1553 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl);
1554 retval = validate_recv_ctrl_frame(adapter, precv_frame);
1555 if (retval == _FAIL) {
1556 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_ctrl_frame fail\n"));
1557 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err);
1558 }
1559 retval = _FAIL;
1560 break;
1561 case WIFI_DATA_TYPE:
1562 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data);
1563
1564 pattrib->qos = (subtype & BIT(7)) ? 1:0;
1565 retval = validate_recv_data_frame(adapter, precv_frame);
1566 if (retval == _FAIL) {
1567 struct recv_priv *precvpriv = &adapter->recvpriv;
1568
1569 precvpriv->rx_drop++;
1570 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err);
1571 } else if (retval == _SUCCESS) {
1572#ifdef DBG_RX_DUMP_EAP
1573 u8 bDumpRxPkt;
1574 u16 eth_type;
1575
1576
1577 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
1578
1579 memcpy(ð_type, ptr + pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE, 2);
1580 eth_type = ntohs((unsigned short) eth_type);
1581 if ((bDumpRxPkt == 4) && (eth_type == 0x888e))
1582 dump_rx_packet(ptr);
1583#endif
1584 } else
1585 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled);
1586 break;
1587 default:
1588 DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown);
1589 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! type = 0x%x\n", type));
1590 #ifdef DBG_RX_DROP_FRAME
1591 DBG_871X("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type = 0x%x\n", type);
1592 #endif
1593 retval = _FAIL;
1594 break;
1595 }
1596
1597exit:
1598 return retval;
1599}
1600
1601
1602
1603sint wlanhdr_to_ethhdr(union recv_frame *precvframe);
1604sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
1605{
1606 sint rmv_len;
1607 u16 eth_type, len;
1608 u8 bsnaphdr;
1609 u8 *psnap_type;
1610 struct ieee80211_snap_hdr *psnap;
1611 __be16 be_tmp;
1612 struct adapter *adapter = precvframe->u.hdr.adapter;
1613 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1614 u8 *ptr = get_recvframe_data(precvframe) ;
1615 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
1616
1617 if (pattrib->encrypt) {
1618 recvframe_pull_tail(precvframe, pattrib->icv_len);
1619 }
1620
1621 psnap = (struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len);
1622 psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE;
1623
1624
1625 if ((!memcmp(psnap, rfc1042_header, SNAP_SIZE) &&
1626 (memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2)) &&
1627 (memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2))) ||
1628
1629 !memcmp(psnap, bridge_tunnel_header, SNAP_SIZE)) {
1630
1631 bsnaphdr = true;
1632 } else
1633
1634 bsnaphdr = false;
1635
1636 rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr?SNAP_SIZE:0);
1637 len = precvframe->u.hdr.len - rmv_len;
1638
1639 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n ===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n\n", pattrib->hdrlen, pattrib->iv_len));
1640
1641 memcpy(&be_tmp, ptr+rmv_len, 2);
1642 eth_type = ntohs(be_tmp);
1643 pattrib->eth_type = eth_type;
1644
1645#ifdef CONFIG_AUTO_AP_MODE
1646 if (0x8899 == pattrib->eth_type) {
1647 struct sta_info *psta = precvframe->u.hdr.psta;
1648
1649 DBG_871X("wlan rx: got eth_type = 0x%x\n", pattrib->eth_type);
1650
1651 if (psta && psta->isrc && psta->pid > 0) {
1652 u16 rx_pid;
1653
1654 rx_pid = *(u16 *)(ptr+rmv_len+2);
1655
1656 DBG_871X("wlan rx(pid = 0x%x): sta("MAC_FMT") pid = 0x%x\n",
1657 rx_pid, MAC_ARG(psta->hwaddr), psta->pid);
1658
1659 if (rx_pid == psta->pid) {
1660 int i;
1661 u16 len = *(u16 *)(ptr+rmv_len+4);
1662
1663
1664
1665 DBG_871X("RC: len = 0x%x\n", len);
1666
1667 for (i = 0; i < len ; i++)
1668 DBG_871X("0x%x\n", *(ptr+rmv_len+6+i));
1669
1670
1671 DBG_871X("RC-end\n");
1672 }
1673 }
1674 }
1675#endif
1676
1677 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) {
1678 ptr += rmv_len;
1679 *ptr = 0x87;
1680 *(ptr+1) = 0x12;
1681
1682 eth_type = 0x8712;
1683
1684 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24);
1685 memcpy(ptr, get_rxmem(precvframe), 24);
1686 ptr += 24;
1687 } else
1688 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr?2:0)));
1689
1690 memcpy(ptr, pattrib->dst, ETH_ALEN);
1691 memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
1692
1693 if (!bsnaphdr) {
1694 be_tmp = htons(len);
1695 memcpy(ptr+12, &be_tmp, 2);
1696 }
1697
1698 return _SUCCESS;
1699}
1700
1701
1702static union recv_frame *recvframe_defrag(struct adapter *adapter,
1703 struct __queue *defrag_q)
1704{
1705 struct list_head *plist, *phead;
1706 u8 wlanhdr_offset;
1707 u8 curfragnum;
1708 struct recv_frame_hdr *pfhdr, *pnfhdr;
1709 union recv_frame *prframe, *pnextrframe;
1710 struct __queue *pfree_recv_queue;
1711
1712 curfragnum = 0;
1713 pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
1714
1715 phead = get_list_head(defrag_q);
1716 plist = get_next(phead);
1717 prframe = (union recv_frame *)plist;
1718 pfhdr = &prframe->u.hdr;
1719 list_del_init(&(prframe->u.list));
1720
1721 if (curfragnum != pfhdr->attrib.frag_num) {
1722
1723
1724 rtw_free_recvframe(prframe, pfree_recv_queue);
1725 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1726
1727 return NULL;
1728 }
1729
1730 curfragnum++;
1731
1732 plist = get_list_head(defrag_q);
1733
1734 plist = get_next(plist);
1735
1736 while (phead != plist) {
1737 pnextrframe = (union recv_frame *)plist;
1738 pnfhdr = &pnextrframe->u.hdr;
1739
1740
1741
1742
1743 if (curfragnum != pnfhdr->attrib.frag_num) {
1744
1745
1746 rtw_free_recvframe(prframe, pfree_recv_queue);
1747 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1748 return NULL;
1749 }
1750
1751 curfragnum++;
1752
1753
1754
1755
1756 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1757
1758 recvframe_pull(pnextrframe, wlanhdr_offset);
1759
1760
1761 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
1762
1763
1764 memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
1765
1766 recvframe_put(prframe, pnfhdr->len);
1767
1768 pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
1769 plist = get_next(plist);
1770
1771 }
1772
1773
1774 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1775
1776 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Performance defrag!!!!!\n"));
1777
1778 return prframe;
1779}
1780
1781
1782union recv_frame *recvframe_chk_defrag(struct adapter *padapter, union recv_frame *precv_frame)
1783{
1784 u8 ismfrag;
1785 u8 fragnum;
1786 u8 *psta_addr;
1787 struct recv_frame_hdr *pfhdr;
1788 struct sta_info *psta;
1789 struct sta_priv *pstapriv;
1790 struct list_head *phead;
1791 union recv_frame *prtnframe = NULL;
1792 struct __queue *pfree_recv_queue, *pdefrag_q;
1793
1794 pstapriv = &padapter->stapriv;
1795
1796 pfhdr = &precv_frame->u.hdr;
1797
1798 pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1799
1800
1801 ismfrag = pfhdr->attrib.mfrag;
1802 fragnum = pfhdr->attrib.frag_num;
1803
1804 psta_addr = pfhdr->attrib.ta;
1805 psta = rtw_get_stainfo(pstapriv, psta_addr);
1806 if (!psta) {
1807 u8 type = GetFrameType(pfhdr->rx_data);
1808 if (type != WIFI_DATA_TYPE) {
1809 psta = rtw_get_bcmc_stainfo(padapter);
1810 pdefrag_q = &psta->sta_recvpriv.defrag_q;
1811 } else
1812 pdefrag_q = NULL;
1813 } else
1814 pdefrag_q = &psta->sta_recvpriv.defrag_q;
1815
1816 if ((ismfrag == 0) && (fragnum == 0))
1817 prtnframe = precv_frame;
1818
1819 if (ismfrag == 1) {
1820
1821
1822 if (pdefrag_q) {
1823 if (fragnum == 0)
1824
1825 if (!list_empty(&pdefrag_q->queue))
1826
1827 rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
1828
1829
1830
1831
1832
1833 phead = get_list_head(pdefrag_q);
1834 list_add_tail(&pfhdr->list, phead);
1835
1836
1837 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Enqueuq: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1838
1839 prtnframe = NULL;
1840
1841 } else {
1842
1843 rtw_free_recvframe(precv_frame, pfree_recv_queue);
1844 prtnframe = NULL;
1845 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1846 }
1847
1848 }
1849
1850 if ((ismfrag == 0) && (fragnum != 0)) {
1851
1852
1853 if (pdefrag_q) {
1854
1855 phead = get_list_head(pdefrag_q);
1856 list_add_tail(&pfhdr->list, phead);
1857
1858
1859
1860 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("defrag: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1861 precv_frame = recvframe_defrag(padapter, pdefrag_q);
1862 prtnframe = precv_frame;
1863
1864 } else {
1865
1866 rtw_free_recvframe(precv_frame, pfree_recv_queue);
1867 prtnframe = NULL;
1868 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum));
1869 }
1870
1871 }
1872
1873
1874 if ((prtnframe) && (prtnframe->u.hdr.attrib.privacy)) {
1875
1876 if (recvframe_chkmic(padapter, prtnframe) == _FAIL) {
1877 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic(padapter, prtnframe) == _FAIL\n"));
1878 rtw_free_recvframe(prtnframe, pfree_recv_queue);
1879 prtnframe = NULL;
1880 }
1881 }
1882 return prtnframe;
1883}
1884
1885static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe)
1886{
1887 int a_len, padding_len;
1888 u16 nSubframe_Length;
1889 u8 nr_subframes, i;
1890 u8 *pdata;
1891 _pkt *sub_pkt, *subframes[MAX_SUBFRAME_COUNT];
1892 struct recv_priv *precvpriv = &padapter->recvpriv;
1893 struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
1894
1895 nr_subframes = 0;
1896
1897 recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
1898
1899 if (prframe->u.hdr.attrib.iv_len > 0)
1900 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
1901
1902 a_len = prframe->u.hdr.len;
1903
1904 pdata = prframe->u.hdr.rx_data;
1905
1906 while (a_len > ETH_HLEN) {
1907
1908
1909 nSubframe_Length = RTW_GET_BE16(pdata + 12);
1910
1911 if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
1912 DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
1913 break;
1914 }
1915
1916 sub_pkt = rtw_os_alloc_msdu_pkt(prframe, nSubframe_Length, pdata);
1917 if (!sub_pkt) {
1918 DBG_871X("%s(): allocate sub packet fail !!!\n", __func__);
1919 break;
1920 }
1921
1922
1923 pdata += ETH_HLEN;
1924 a_len -= ETH_HLEN;
1925
1926 subframes[nr_subframes++] = sub_pkt;
1927
1928 if (nr_subframes >= MAX_SUBFRAME_COUNT) {
1929 DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n");
1930 break;
1931 }
1932
1933 pdata += nSubframe_Length;
1934 a_len -= nSubframe_Length;
1935 if (a_len != 0) {
1936 padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1));
1937 if (padding_len == 4) {
1938 padding_len = 0;
1939 }
1940
1941 if (a_len < padding_len) {
1942 DBG_871X("ParseSubframe(): a_len < padding_len !\n");
1943 break;
1944 }
1945 pdata += padding_len;
1946 a_len -= padding_len;
1947 }
1948 }
1949
1950 for (i = 0; i < nr_subframes; i++) {
1951 sub_pkt = subframes[i];
1952
1953
1954 if (sub_pkt) {
1955 rtw_os_recv_indicate_pkt(padapter, sub_pkt, &prframe->u.hdr.attrib);
1956 }
1957 }
1958
1959 prframe->u.hdr.len = 0;
1960 rtw_free_recvframe(prframe, pfree_recv_queue);
1961
1962 return _SUCCESS;
1963}
1964
1965int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
1966int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
1967{
1968 struct adapter *padapter = preorder_ctrl->padapter;
1969 struct dvobj_priv *psdpriv = padapter->dvobj;
1970 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1971 u8 wsize = preorder_ctrl->wsize_b;
1972 u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;
1973
1974
1975 if (preorder_ctrl->indicate_seq == 0xFFFF) {
1976 preorder_ctrl->indicate_seq = seq_num;
1977 #ifdef DBG_RX_SEQ
1978 DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
1979 preorder_ctrl->indicate_seq, seq_num);
1980 #endif
1981
1982
1983 }
1984
1985
1986
1987
1988 if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) {
1989
1990
1991
1992 #ifdef DBG_RX_DROP_FRAME
1993 DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __func__,
1994 preorder_ctrl->indicate_seq, seq_num);
1995 #endif
1996
1997
1998 return false;
1999 }
2000
2001
2002
2003
2004
2005
2006 if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
2007 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2008
2009 #ifdef DBG_RX_SEQ
2010 DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2011 preorder_ctrl->indicate_seq, seq_num);
2012 #endif
2013 } else if (SN_LESS(wend, seq_num)) {
2014
2015
2016
2017
2018 if (seq_num >= (wsize - 1))
2019 preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
2020 else
2021 preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
2022 pdbgpriv->dbg_rx_ampdu_window_shift_cnt++;
2023 #ifdef DBG_RX_SEQ
2024 DBG_871X("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2025 preorder_ctrl->indicate_seq, seq_num);
2026 #endif
2027 }
2028
2029
2030
2031 return true;
2032}
2033
2034int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe);
2035int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe)
2036{
2037 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2038 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2039 struct list_head *phead, *plist;
2040 union recv_frame *pnextrframe;
2041 struct rx_pkt_attrib *pnextattrib;
2042
2043
2044
2045
2046
2047
2048
2049 phead = get_list_head(ppending_recvframe_queue);
2050 plist = get_next(phead);
2051
2052 while (phead != plist) {
2053 pnextrframe = (union recv_frame *)plist;
2054 pnextattrib = &pnextrframe->u.hdr.attrib;
2055
2056 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
2057 plist = get_next(plist);
2058 else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
2059
2060
2061
2062 return false;
2063 else
2064 break;
2065
2066
2067
2068 }
2069
2070
2071
2072
2073
2074 list_del_init(&(prframe->u.hdr.list));
2075
2076 list_add_tail(&(prframe->u.hdr.list), plist);
2077
2078
2079
2080
2081
2082
2083 return true;
2084
2085}
2086
2087void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq);
2088void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq)
2089{
2090 if (current_seq < prev_seq)
2091 pdbgpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq);
2092 else
2093 pdbgpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq);
2094
2095}
2096int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced);
2097int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
2098{
2099 struct list_head *phead, *plist;
2100 union recv_frame *prframe;
2101 struct rx_pkt_attrib *pattrib;
2102
2103 int bPktInBuf = false;
2104 struct recv_priv *precvpriv = &padapter->recvpriv;
2105 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2106 struct dvobj_priv *psdpriv = padapter->dvobj;
2107 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
2108
2109 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder);
2110
2111
2112
2113
2114
2115
2116 phead = get_list_head(ppending_recvframe_queue);
2117 plist = get_next(phead);
2118
2119
2120 if (bforced == true) {
2121 pdbgpriv->dbg_rx_ampdu_forced_indicate_count++;
2122 if (list_empty(phead)) {
2123
2124
2125 return true;
2126 }
2127
2128 prframe = (union recv_frame *)plist;
2129 pattrib = &prframe->u.hdr.attrib;
2130
2131 #ifdef DBG_RX_SEQ
2132 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2133 preorder_ctrl->indicate_seq, pattrib->seq_num);
2134 #endif
2135 recv_indicatepkts_pkt_loss_cnt(pdbgpriv, preorder_ctrl->indicate_seq, pattrib->seq_num);
2136 preorder_ctrl->indicate_seq = pattrib->seq_num;
2137
2138 }
2139
2140
2141
2142 while (!list_empty(phead)) {
2143
2144 prframe = (union recv_frame *)plist;
2145 pattrib = &prframe->u.hdr.attrib;
2146
2147 if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
2148 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2149 ("recv_indicatepkts_in_order: indicate =%d seq =%d amsdu =%d\n",
2150 preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu));
2151
2152 plist = get_next(plist);
2153 list_del_init(&(prframe->u.hdr.list));
2154
2155 if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
2156 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
2157 #ifdef DBG_RX_SEQ
2158 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2159 preorder_ctrl->indicate_seq, pattrib->seq_num);
2160 #endif
2161 }
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172 if (!pattrib->amsdu) {
2173
2174
2175 if ((padapter->bDriverStopped == false) &&
2176 (padapter->bSurpriseRemoved == false))
2177 rtw_recv_indicatepkt(padapter, prframe);
2178
2179 } else if (pattrib->amsdu == 1) {
2180 if (amsdu_to_msdu(padapter, prframe) != _SUCCESS)
2181 rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
2182
2183 } else {
2184
2185 }
2186
2187
2188
2189 bPktInBuf = false;
2190
2191 } else {
2192 bPktInBuf = true;
2193 break;
2194 }
2195
2196
2197
2198 }
2199
2200
2201
2202
2203 return bPktInBuf;
2204}
2205
2206int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *prframe);
2207int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *prframe)
2208{
2209 int retval = _SUCCESS;
2210 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
2211 struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
2212 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2213 struct dvobj_priv *psdpriv = padapter->dvobj;
2214 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
2215
2216 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder);
2217
2218 if (!pattrib->amsdu) {
2219
2220 wlanhdr_to_ethhdr(prframe);
2221
2222 if (pattrib->qos != 1) {
2223 if ((padapter->bDriverStopped == false) &&
2224 (padapter->bSurpriseRemoved == false)) {
2225 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n"));
2226
2227 rtw_recv_indicatepkt(padapter, prframe);
2228 return _SUCCESS;
2229
2230 }
2231
2232 #ifdef DBG_RX_DROP_FRAME
2233 DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos != 1\n", __func__);
2234 #endif
2235
2236 return _FAIL;
2237
2238 }
2239
2240 if (preorder_ctrl->enable == false) {
2241
2242 preorder_ctrl->indicate_seq = pattrib->seq_num;
2243 #ifdef DBG_RX_SEQ
2244 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2245 preorder_ctrl->indicate_seq, pattrib->seq_num);
2246 #endif
2247
2248 rtw_recv_indicatepkt(padapter, prframe);
2249
2250 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
2251 #ifdef DBG_RX_SEQ
2252 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2253 preorder_ctrl->indicate_seq, pattrib->seq_num);
2254 #endif
2255
2256 return _SUCCESS;
2257 }
2258 } else if (pattrib->amsdu == 1) {
2259 if (preorder_ctrl->enable == false) {
2260 preorder_ctrl->indicate_seq = pattrib->seq_num;
2261 #ifdef DBG_RX_SEQ
2262 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2263 preorder_ctrl->indicate_seq, pattrib->seq_num);
2264 #endif
2265
2266 retval = amsdu_to_msdu(padapter, prframe);
2267
2268 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
2269 #ifdef DBG_RX_SEQ
2270 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__,
2271 preorder_ctrl->indicate_seq, pattrib->seq_num);
2272 #endif
2273
2274 if (retval != _SUCCESS) {
2275 #ifdef DBG_RX_DROP_FRAME
2276 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __func__);
2277 #endif
2278 }
2279
2280 return retval;
2281 }
2282 }
2283
2284 spin_lock_bh(&ppending_recvframe_queue->lock);
2285
2286 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2287 ("recv_indicatepkt_reorder: indicate =%d seq =%d\n",
2288 preorder_ctrl->indicate_seq, pattrib->seq_num));
2289
2290
2291 if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
2292 pdbgpriv->dbg_rx_ampdu_drop_count++;
2293 #ifdef DBG_RX_DROP_FRAME
2294 DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __func__);
2295 #endif
2296 goto _err_exit;
2297 }
2298
2299
2300
2301 if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) {
2302
2303
2304
2305 #ifdef DBG_RX_DROP_FRAME
2306 DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __func__);
2307 #endif
2308 goto _err_exit;
2309 }
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) {
2324 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
2325 spin_unlock_bh(&ppending_recvframe_queue->lock);
2326 } else {
2327 spin_unlock_bh(&ppending_recvframe_queue->lock);
2328 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
2329 }
2330
2331 return _SUCCESS;
2332
2333_err_exit:
2334 spin_unlock_bh(&ppending_recvframe_queue->lock);
2335
2336 return _FAIL;
2337}
2338
2339
2340void rtw_reordering_ctrl_timeout_handler(struct timer_list *t)
2341{
2342 struct recv_reorder_ctrl *preorder_ctrl =
2343 from_timer(preorder_ctrl, t, reordering_ctrl_timer);
2344 struct adapter *padapter = preorder_ctrl->padapter;
2345 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2346
2347
2348 if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
2349 return;
2350
2351
2352
2353 spin_lock_bh(&ppending_recvframe_queue->lock);
2354
2355 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true)
2356 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
2357
2358 spin_unlock_bh(&ppending_recvframe_queue->lock);
2359
2360}
2361
2362int process_recv_indicatepkts(struct adapter *padapter, union recv_frame *prframe);
2363int process_recv_indicatepkts(struct adapter *padapter, union recv_frame *prframe)
2364{
2365 int retval = _SUCCESS;
2366
2367
2368 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2369 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2370
2371 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate);
2372
2373 if (phtpriv->ht_option == true) {
2374
2375
2376 if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
2377 #ifdef DBG_RX_DROP_FRAME
2378 DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __func__);
2379 #endif
2380
2381 if ((padapter->bDriverStopped == false) &&
2382 (padapter->bSurpriseRemoved == false)) {
2383 retval = _FAIL;
2384 return retval;
2385 }
2386 }
2387 } else {
2388 retval = wlanhdr_to_ethhdr(prframe);
2389 if (retval != _SUCCESS) {
2390 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n"));
2391 #ifdef DBG_RX_DROP_FRAME
2392 DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __func__);
2393 #endif
2394 return retval;
2395 }
2396
2397 if ((padapter->bDriverStopped == false) && (padapter->bSurpriseRemoved == false)) {
2398
2399 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n"));
2400 rtw_recv_indicatepkt(padapter, prframe);
2401
2402
2403 } else {
2404 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n"));
2405
2406 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
2407 retval = _FAIL;
2408 return retval;
2409 }
2410
2411 }
2412
2413 return retval;
2414
2415}
2416
2417static int recv_func_prehandle(struct adapter *padapter, union recv_frame *rframe)
2418{
2419 int ret = _SUCCESS;
2420 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2421
2422 DBG_COUNTER(padapter->rx_logs.core_rx_pre);
2423
2424
2425 ret = validate_recv_frame(padapter, rframe);
2426 if (ret != _SUCCESS) {
2427 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n"));
2428 rtw_free_recvframe(rframe, pfree_recv_queue);
2429 goto exit;
2430 }
2431
2432exit:
2433 return ret;
2434}
2435
2436static int recv_func_posthandle(struct adapter *padapter, union recv_frame *prframe)
2437{
2438 int ret = _SUCCESS;
2439 union recv_frame *orig_prframe = prframe;
2440 struct recv_priv *precvpriv = &padapter->recvpriv;
2441 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2442
2443 DBG_COUNTER(padapter->rx_logs.core_rx_post);
2444
2445 prframe = decryptor(padapter, prframe);
2446 if (!prframe) {
2447 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decryptor: drop pkt\n"));
2448 #ifdef DBG_RX_DROP_FRAME
2449 DBG_871X("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __func__);
2450 #endif
2451 ret = _FAIL;
2452 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err);
2453 goto _recv_data_drop;
2454 }
2455
2456 prframe = recvframe_chk_defrag(padapter, prframe);
2457 if (!prframe) {
2458 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chk_defrag: drop pkt\n"));
2459 #ifdef DBG_RX_DROP_FRAME
2460 DBG_871X("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __func__);
2461 #endif
2462 DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err);
2463 goto _recv_data_drop;
2464 }
2465
2466 prframe = portctrl(padapter, prframe);
2467 if (!prframe) {
2468 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("portctrl: drop pkt\n"));
2469 #ifdef DBG_RX_DROP_FRAME
2470 DBG_871X("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __func__);
2471 #endif
2472 ret = _FAIL;
2473 DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err);
2474 goto _recv_data_drop;
2475 }
2476
2477 count_rx_stats(padapter, prframe, NULL);
2478
2479 ret = process_recv_indicatepkts(padapter, prframe);
2480 if (ret != _SUCCESS) {
2481 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recv_func: process_recv_indicatepkts fail!\n"));
2482 #ifdef DBG_RX_DROP_FRAME
2483 DBG_871X("DBG_RX_DROP_FRAME %s process_recv_indicatepkts fail!\n", __func__);
2484 #endif
2485 rtw_free_recvframe(orig_prframe, pfree_recv_queue);
2486 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_err);
2487 goto _recv_data_drop;
2488 }
2489
2490_recv_data_drop:
2491 precvpriv->rx_drop++;
2492 return ret;
2493}
2494
2495
2496int recv_func(struct adapter *padapter, union recv_frame *rframe);
2497int recv_func(struct adapter *padapter, union recv_frame *rframe)
2498{
2499 int ret;
2500 struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
2501 struct recv_priv *recvpriv = &padapter->recvpriv;
2502 struct security_priv *psecuritypriv = &padapter->securitypriv;
2503 struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2504
2505
2506 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) {
2507 union recv_frame *pending_frame;
2508 int cnt = 0;
2509
2510 while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) {
2511 cnt++;
2512 DBG_COUNTER(padapter->rx_logs.core_rx_dequeue);
2513 recv_func_posthandle(padapter, pending_frame);
2514 }
2515
2516 if (cnt)
2517 DBG_871X(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n",
2518 FUNC_ADPT_ARG(padapter), cnt);
2519 }
2520
2521 DBG_COUNTER(padapter->rx_logs.core_rx);
2522 ret = recv_func_prehandle(padapter, rframe);
2523
2524 if (ret == _SUCCESS) {
2525
2526
2527 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2528 !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 &&
2529 (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt == true) &&
2530 psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
2531 !psecuritypriv->busetkipkey) {
2532 DBG_COUNTER(padapter->rx_logs.core_rx_enqueue);
2533 rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
2534
2535
2536 if (recvpriv->free_recvframe_cnt < NR_RECVFRAME/4) {
2537
2538 rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
2539 if (rframe)
2540 goto do_posthandle;
2541 }
2542 goto exit;
2543 }
2544
2545do_posthandle:
2546 ret = recv_func_posthandle(padapter, rframe);
2547 }
2548
2549exit:
2550 return ret;
2551}
2552
2553
2554s32 rtw_recv_entry(union recv_frame *precvframe)
2555{
2556 struct adapter *padapter;
2557 struct recv_priv *precvpriv;
2558 s32 ret = _SUCCESS;
2559
2560
2561
2562 padapter = precvframe->u.hdr.adapter;
2563
2564 precvpriv = &padapter->recvpriv;
2565
2566 ret = recv_func(padapter, precvframe);
2567 if (ret == _FAIL) {
2568 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtw_recv_entry: recv_func return fail!!!\n"));
2569 goto _recv_entry_drop;
2570 }
2571
2572
2573 precvpriv->rx_pkts++;
2574
2575 return ret;
2576
2577_recv_entry_drop:
2578
2579
2580
2581 return ret;
2582}
2583
2584static void rtw_signal_stat_timer_hdl(struct timer_list *t)
2585{
2586 struct adapter *adapter =
2587 from_timer(adapter, t, recvpriv.signal_stat_timer);
2588 struct recv_priv *recvpriv = &adapter->recvpriv;
2589
2590 u32 tmp_s, tmp_q;
2591 u8 avg_signal_strength = 0;
2592 u8 avg_signal_qual = 0;
2593 u32 num_signal_strength = 0;
2594 u32 num_signal_qual = 0;
2595 u8 _alpha = 5;
2596
2597 if (adapter->recvpriv.is_signal_dbg) {
2598
2599 adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
2600 adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
2601 } else {
2602
2603 if (recvpriv->signal_strength_data.update_req == 0) {
2604 avg_signal_strength = recvpriv->signal_strength_data.avg_val;
2605 num_signal_strength = recvpriv->signal_strength_data.total_num;
2606
2607 recvpriv->signal_strength_data.update_req = 1;
2608 }
2609
2610 if (recvpriv->signal_qual_data.update_req == 0) {
2611 avg_signal_qual = recvpriv->signal_qual_data.avg_val;
2612 num_signal_qual = recvpriv->signal_qual_data.total_num;
2613
2614 recvpriv->signal_qual_data.update_req = 1;
2615 }
2616
2617 if (num_signal_strength == 0) {
2618 if (rtw_get_on_cur_ch_time(adapter) == 0
2619 || jiffies_to_msecs(jiffies - rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval
2620 ) {
2621 goto set_timer;
2622 }
2623 }
2624
2625 if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == true
2626 || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == false
2627 ) {
2628 goto set_timer;
2629 }
2630
2631
2632 tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength);
2633 if (tmp_s % _alpha)
2634 tmp_s = tmp_s/_alpha + 1;
2635 else
2636 tmp_s = tmp_s/_alpha;
2637 if (tmp_s > 100)
2638 tmp_s = 100;
2639
2640 tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual);
2641 if (tmp_q % _alpha)
2642 tmp_q = tmp_q/_alpha + 1;
2643 else
2644 tmp_q = tmp_q/_alpha;
2645 if (tmp_q > 100)
2646 tmp_q = 100;
2647
2648 recvpriv->signal_strength = tmp_s;
2649 recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
2650 recvpriv->signal_qual = tmp_q;
2651
2652 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
2653 DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
2654 ", num_signal_strength:%u, num_signal_qual:%u"
2655 ", on_cur_ch_ms:%d"
2656 "\n"
2657 , FUNC_ADPT_ARG(adapter)
2658 , recvpriv->signal_strength
2659 , recvpriv->rssi
2660 , recvpriv->signal_qual
2661 , num_signal_strength, num_signal_qual
2662 , rtw_get_on_cur_ch_time(adapter) ? jiffies_to_msecs(jiffies - rtw_get_on_cur_ch_time(adapter)) : 0
2663 );
2664 #endif
2665 }
2666
2667set_timer:
2668 rtw_set_signal_stat_timer(recvpriv);
2669
2670}
2671