xref: /OK3568_Linux_fs/external/rkwifibt/drivers/rtl8852bs/core/rtw_recv.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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(&ether_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(&ether_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(&eth_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(&eth_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(&eth_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, &param);
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