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