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