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