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