• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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 #include <osdep_service.h>
17 #include <drv_types.h>
18 #include <recv_osdep.h>
19 #include <mlme_osdep.h>
20 #include <linux/ip.h>
21 #include <linux/if_ether.h>
22 #include <usb_ops.h>
23 #include <linux/ieee80211.h>
24 #include <wifi.h>
25 #include <rtl8723a_recv.h>
26 #include <rtl8723a_xmit.h>
27 
28 void rtw_signal_stat_timer_hdl23a(unsigned long data);
29 
_rtw_init_sta_recv_priv23a(struct sta_recv_priv * psta_recvpriv)30 void _rtw_init_sta_recv_priv23a(struct sta_recv_priv *psta_recvpriv)
31 {
32 
33 
34 
35 	spin_lock_init(&psta_recvpriv->lock);
36 
37 	/* for (i = 0; i<MAX_RX_NUMBLKS; i++) */
38 	/*	_rtw_init_queue23a(&psta_recvpriv->blk_strms[i]); */
39 
40 	_rtw_init_queue23a(&psta_recvpriv->defrag_q);
41 
42 
43 }
44 
_rtw_init_recv_priv23a(struct recv_priv * precvpriv,struct rtw_adapter * padapter)45 int _rtw_init_recv_priv23a(struct recv_priv *precvpriv,
46 			struct rtw_adapter *padapter)
47 {
48 	struct recv_frame *precvframe;
49 	int i;
50 	int res = _SUCCESS;
51 
52 	spin_lock_init(&precvpriv->lock);
53 
54 	_rtw_init_queue23a(&precvpriv->free_recv_queue);
55 	_rtw_init_queue23a(&precvpriv->recv_pending_queue);
56 	_rtw_init_queue23a(&precvpriv->uc_swdec_pending_queue);
57 
58 	precvpriv->adapter = padapter;
59 
60 	for (i = 0; i < NR_RECVFRAME ; i++) {
61 		precvframe = kzalloc(sizeof(struct recv_frame), GFP_KERNEL);
62 		if (!precvframe)
63 			break;
64 		INIT_LIST_HEAD(&precvframe->list);
65 
66 		list_add_tail(&precvframe->list,
67 			      &precvpriv->free_recv_queue.queue);
68 
69 		precvframe->adapter = padapter;
70 		precvframe++;
71 	}
72 
73 	precvpriv->free_recvframe_cnt = i;
74 	precvpriv->rx_pending_cnt = 1;
75 
76 	res = rtl8723au_init_recv_priv(padapter);
77 
78 	setup_timer(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl23a,
79 		    (unsigned long)padapter);
80 
81 	precvpriv->signal_stat_sampling_interval = 1000; /* ms */
82 
83 	rtw_set_signal_stat_timer(precvpriv);
84 
85 	return res;
86 }
87 
_rtw_free_recv_priv23a(struct recv_priv * precvpriv)88 void _rtw_free_recv_priv23a (struct recv_priv *precvpriv)
89 {
90 	struct rtw_adapter *padapter = precvpriv->adapter;
91 	struct recv_frame *precvframe;
92 	struct list_head *plist, *ptmp;
93 
94 	rtw_free_uc_swdec_pending_queue23a(padapter);
95 
96 	list_for_each_safe(plist, ptmp, &precvpriv->free_recv_queue.queue) {
97 		precvframe = container_of(plist, struct recv_frame, list);
98 		list_del_init(&precvframe->list);
99 		kfree(precvframe);
100 	}
101 
102 	rtl8723au_free_recv_priv(padapter);
103 }
104 
rtw_alloc_recvframe23a(struct rtw_queue * pfree_recv_queue)105 struct recv_frame *rtw_alloc_recvframe23a(struct rtw_queue *pfree_recv_queue)
106 {
107 	struct recv_frame *pframe;
108 	struct list_head *plist, *phead;
109 	struct rtw_adapter *padapter;
110 	struct recv_priv *precvpriv;
111 
112 	spin_lock_bh(&pfree_recv_queue->lock);
113 
114 	if (list_empty(&pfree_recv_queue->queue))
115 		pframe = NULL;
116 	else {
117 		phead = get_list_head(pfree_recv_queue);
118 
119 		plist = phead->next;
120 
121 		pframe = container_of(plist, struct recv_frame, list);
122 
123 		list_del_init(&pframe->list);
124 		padapter = pframe->adapter;
125 		if (padapter) {
126 			precvpriv = &padapter->recvpriv;
127 			if (pfree_recv_queue == &precvpriv->free_recv_queue)
128 				precvpriv->free_recvframe_cnt--;
129 		}
130 	}
131 
132 	spin_unlock_bh(&pfree_recv_queue->lock);
133 
134 	return pframe;
135 }
136 
rtw_free_recvframe23a(struct recv_frame * precvframe)137 int rtw_free_recvframe23a(struct recv_frame *precvframe)
138 {
139 	struct rtw_adapter *padapter = precvframe->adapter;
140 	struct recv_priv *precvpriv = &padapter->recvpriv;
141 	struct rtw_queue *pfree_recv_queue;
142 
143 	if (precvframe->pkt) {
144 		dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */
145 		precvframe->pkt = NULL;
146 	}
147 
148 	pfree_recv_queue = &precvpriv->free_recv_queue;
149 	spin_lock_bh(&pfree_recv_queue->lock);
150 
151 	list_del_init(&precvframe->list);
152 
153 	list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
154 
155 	if (padapter) {
156 		if (pfree_recv_queue == &precvpriv->free_recv_queue)
157 			precvpriv->free_recvframe_cnt++;
158 	}
159 
160 	spin_unlock_bh(&pfree_recv_queue->lock);
161 
162 
163 
164 	return _SUCCESS;
165 }
166 
rtw_enqueue_recvframe23a(struct recv_frame * precvframe,struct rtw_queue * queue)167 int rtw_enqueue_recvframe23a(struct recv_frame *precvframe, struct rtw_queue *queue)
168 {
169 	struct rtw_adapter *padapter = precvframe->adapter;
170 	struct recv_priv *precvpriv = &padapter->recvpriv;
171 
172 	spin_lock_bh(&queue->lock);
173 
174 	list_del_init(&precvframe->list);
175 
176 	list_add_tail(&precvframe->list, get_list_head(queue));
177 
178 	if (padapter) {
179 		if (queue == &precvpriv->free_recv_queue)
180 			precvpriv->free_recvframe_cnt++;
181 	}
182 
183 	spin_unlock_bh(&queue->lock);
184 
185 	return _SUCCESS;
186 }
187 
188 /*
189 caller : defrag ; recvframe_chk_defrag23a in recv_thread  (passive)
190 pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
191 
192 using spinlock to protect
193 
194 */
195 
rtw_free_recvframe23a_queue(struct rtw_queue * pframequeue)196 static void rtw_free_recvframe23a_queue(struct rtw_queue *pframequeue)
197 {
198 	struct recv_frame *hdr;
199 	struct list_head *plist, *phead, *ptmp;
200 
201 	spin_lock(&pframequeue->lock);
202 
203 	phead = get_list_head(pframequeue);
204 	plist = phead->next;
205 
206 	list_for_each_safe(plist, ptmp, phead) {
207 		hdr = container_of(plist, struct recv_frame, list);
208 		rtw_free_recvframe23a(hdr);
209 	}
210 
211 	spin_unlock(&pframequeue->lock);
212 }
213 
rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter * adapter)214 u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter)
215 {
216 	u32 cnt = 0;
217 	struct recv_frame *pending_frame;
218 	while ((pending_frame = rtw_alloc_recvframe23a(&adapter->recvpriv.uc_swdec_pending_queue))) {
219 		rtw_free_recvframe23a(pending_frame);
220 		DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
221 		cnt++;
222 	}
223 
224 	return cnt;
225 }
226 
rtw_enqueue_recvbuf23a_to_head(struct recv_buf * precvbuf,struct rtw_queue * queue)227 int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue *queue)
228 {
229 	spin_lock_bh(&queue->lock);
230 
231 	list_del_init(&precvbuf->list);
232 	list_add(&precvbuf->list, get_list_head(queue));
233 
234 	spin_unlock_bh(&queue->lock);
235 
236 	return _SUCCESS;
237 }
238 
rtw_enqueue_recvbuf23a(struct recv_buf * precvbuf,struct rtw_queue * queue)239 int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue)
240 {
241 	unsigned long irqL;
242 	spin_lock_irqsave(&queue->lock, irqL);
243 
244 	list_del_init(&precvbuf->list);
245 
246 	list_add_tail(&precvbuf->list, get_list_head(queue));
247 	spin_unlock_irqrestore(&queue->lock, irqL);
248 	return _SUCCESS;
249 }
250 
rtw_dequeue_recvbuf23a(struct rtw_queue * queue)251 struct recv_buf *rtw_dequeue_recvbuf23a (struct rtw_queue *queue)
252 {
253 	unsigned long irqL;
254 	struct recv_buf *precvbuf;
255 	struct list_head *plist, *phead;
256 
257 	spin_lock_irqsave(&queue->lock, irqL);
258 
259 	if (list_empty(&queue->queue)) {
260 		precvbuf = NULL;
261 	} else {
262 		phead = get_list_head(queue);
263 
264 		plist = phead->next;
265 
266 		precvbuf = container_of(plist, struct recv_buf, list);
267 
268 		list_del_init(&precvbuf->list);
269 	}
270 
271 	spin_unlock_irqrestore(&queue->lock, irqL);
272 
273 	return precvbuf;
274 }
275 
276 int recvframe_chkmic(struct rtw_adapter *adapter,
277 		     struct recv_frame *precvframe);
recvframe_chkmic(struct rtw_adapter * adapter,struct recv_frame * precvframe)278 int recvframe_chkmic(struct rtw_adapter *adapter,
279 		     struct recv_frame *precvframe) {
280 
281 	int	i, res = _SUCCESS;
282 	u32	datalen;
283 	u8	miccode[8];
284 	u8	bmic_err = false, brpt_micerror = true;
285 	u8	*pframe, *payload, *pframemic;
286 	u8	*mickey;
287 	/* u8	*iv, rxdata_key_idx = 0; */
288 	struct	sta_info *stainfo;
289 	struct	rx_pkt_attrib *prxattrib = &precvframe->attrib;
290 	struct	security_priv *psecuritypriv = &adapter->securitypriv;
291 
292 	struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
293 	struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
294 
295 
296 	stainfo = rtw_get_stainfo23a(&adapter->stapriv, &prxattrib->ta[0]);
297 
298 	if (prxattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) {
299 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
300 			 ("\n recvframe_chkmic:prxattrib->encrypt == WLAN_CIPHER_SUITE_TKIP\n"));
301 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
302 			 ("\n recvframe_chkmic:da = 0x%02x:0x%02x:0x%02x:0x%02x:"
303 			  "0x%02x:0x%02x\n", prxattrib->ra[0],
304 			  prxattrib->ra[1], prxattrib->ra[2], prxattrib->ra[3],
305 			  prxattrib->ra[4], prxattrib->ra[5]));
306 
307 		/* calculate mic code */
308 		if (stainfo != NULL) {
309 			if (is_multicast_ether_addr(prxattrib->ra)) {
310 				mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
311 
312 				RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
313 					 ("\n recvframe_chkmic: bcmc key\n"));
314 
315 				if (!psecuritypriv->binstallGrpkey) {
316 					res = _FAIL;
317 					RT_TRACE(_module_rtl871x_recv_c_,
318 						 _drv_err_,
319 						 ("\n recvframe_chkmic:didn't "
320 						  "install group key!!!!!!\n"));
321 					DBG_8723A("\n recvframe_chkmic:didn't "
322 						  "install group key!!!!!!\n");
323 					goto exit;
324 				}
325 			} else {
326 				mickey = &stainfo->dot11tkiprxmickey.skey[0];
327 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
328 					 ("\n recvframe_chkmic: unicast "
329 					  "key\n"));
330 			}
331 
332 			/* icv_len included the mic code */
333 			datalen = precvframe->pkt->len-prxattrib->
334 				hdrlen-prxattrib->iv_len-prxattrib->icv_len - 8;
335 			pframe = precvframe->pkt->data;
336 			payload = pframe + prxattrib->hdrlen +
337 				prxattrib->iv_len;
338 
339 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
340 				 ("\n prxattrib->iv_len =%d prxattrib->icv_len ="
341 				  "%d\n", prxattrib->iv_len,
342 				  prxattrib->icv_len));
343 
344 			/* care the length of the data */
345 			rtw_seccalctkipmic23a(mickey, pframe, payload,
346 					   datalen, &miccode[0],
347 					   (unsigned char)prxattrib->priority);
348 
349 			pframemic = payload + datalen;
350 
351 			bmic_err = false;
352 
353 			for (i = 0; i < 8; i++) {
354 				if (miccode[i] != *(pframemic + i)) {
355 					RT_TRACE(_module_rtl871x_recv_c_,
356 						 _drv_err_,
357 						 ("recvframe_chkmic:miccode"
358 						  "[%d](%02x) != *(pframemic+"
359 						  "%d)(%02x) ", i, miccode[i],
360 						  i, *(pframemic + i)));
361 					bmic_err = true;
362 				}
363 			}
364 
365 			if (bmic_err == true) {
366 				int i;
367 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
368 					 ("\n *(pframemic-8)-*(pframemic-1) ="
369 					  "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:"
370 					  "0x%02x:0x%02x:0x%02x\n",
371 					  *(pframemic - 8), *(pframemic - 7),
372 					  *(pframemic - 6), *(pframemic - 5),
373 					  *(pframemic - 4), *(pframemic - 3),
374 					  *(pframemic - 2), *(pframemic - 1)));
375 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
376 					 ("\n *(pframemic-16)-*(pframemic-9) ="
377 					  "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:"
378 					  "0x%02x:0x%02x:0x%02x\n",
379 					  *(pframemic - 16), *(pframemic - 15),
380 					  *(pframemic - 14), *(pframemic - 13),
381 					  *(pframemic - 12), *(pframemic - 11),
382 					  *(pframemic - 10), *(pframemic - 9)));
383 
384 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
385 					 ("\n ====== demp packet (len =%d) ======"
386 					  "\n", precvframe->pkt->len));
387 				for (i = 0; i < precvframe->pkt->len; i = i + 8) {
388 					RT_TRACE(_module_rtl871x_recv_c_,
389 						 _drv_err_, ("0x%02x:0x%02x:0x"
390 							    "%02x:0x%02x:0x%0"
391 							    "2x:0x%02x:0x%02x"
392 							    ":0x%02x",
393 							    *(precvframe->pkt->data+i),*(precvframe->pkt->data+i+1),
394 							    *(precvframe->pkt->data+i+2),*(precvframe->pkt->data+i+3),
395 							    *(precvframe->pkt->data+i+4),*(precvframe->pkt->data+i+5),
396 							    *(precvframe->pkt->data+i+6),*(precvframe->pkt->data+i+7)));
397 				}
398 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
399 					 ("\n ====== demp packet end [len =%d]"
400 					  "======\n", precvframe->pkt->len));
401 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
402 					 ("\n hrdlen =%d,\n",
403 					  prxattrib->hdrlen));
404 
405 				RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
406 					 ("ra = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%."
407 					  "2x 0x%.2x psecuritypriv->"
408 					  "binstallGrpkey =%d ",
409 					  prxattrib->ra[0], prxattrib->ra[1],
410 					  prxattrib->ra[2], prxattrib->ra[3],
411 					  prxattrib->ra[4], prxattrib->ra[5],
412 					  psecuritypriv->binstallGrpkey));
413 
414 				/*  double check key_index for some timing
415 				    issue, cannot compare with
416 				    psecuritypriv->dot118021XGrpKeyid also
417 				    cause timing issue */
418 				if ((is_multicast_ether_addr(prxattrib->ra)) &&
419 				    (prxattrib->key_index !=
420 				     pmlmeinfo->key_index))
421 					brpt_micerror = false;
422 
423 				if ((prxattrib->bdecrypted == true) &&
424 				    (brpt_micerror == true)) {
425 					rtw_handle_tkip_mic_err23a(adapter, (u8)is_multicast_ether_addr(prxattrib->ra));
426 					RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted));
427 					DBG_8723A(" mic error :prxattrib->"
428 						  "bdecrypted =%d\n",
429 						  prxattrib->bdecrypted);
430 				} else {
431 					RT_TRACE(_module_rtl871x_recv_c_,
432 						 _drv_err_,
433 						 (" mic error :prxattrib->"
434 						  "bdecrypted =%d ",
435 						  prxattrib->bdecrypted));
436 					DBG_8723A(" mic error :prxattrib->"
437 						  "bdecrypted =%d\n",
438 						  prxattrib->bdecrypted);
439 				}
440 
441 				res = _FAIL;
442 			} else {
443 				/* mic checked ok */
444 				if (!psecuritypriv->bcheck_grpkey &&
445 				    is_multicast_ether_addr(prxattrib->ra)) {
446 					psecuritypriv->bcheck_grpkey = 1;
447 					RT_TRACE(_module_rtl871x_recv_c_,
448 						 _drv_err_,
449 						 ("psecuritypriv->bcheck_grp"
450 						  "key = true"));
451 				}
452 			}
453 		} else {
454 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
455 				 ("recvframe_chkmic: rtw_get_stainfo23a =="
456 				  "NULL!!!\n"));
457 		}
458 
459 		skb_trim(precvframe->pkt, precvframe->pkt->len - 8);
460 	}
461 
462 exit:
463 
464 
465 
466 	return res;
467 }
468 
469 /* decrypt and set the ivlen, icvlen of the recv_frame */
470 struct recv_frame *decryptor(struct rtw_adapter *padapter,
471 			     struct recv_frame *precv_frame);
decryptor(struct rtw_adapter * padapter,struct recv_frame * precv_frame)472 struct recv_frame *decryptor(struct rtw_adapter *padapter,
473 			     struct recv_frame *precv_frame)
474 {
475 	struct rx_pkt_attrib *prxattrib = &precv_frame->attrib;
476 	struct security_priv *psecuritypriv = &padapter->securitypriv;
477 	struct recv_frame *return_packet = precv_frame;
478 	int res = _SUCCESS;
479 
480 	RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
481 		 ("prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n",
482 		  prxattrib->bdecrypted, prxattrib->encrypt));
483 
484 	if (prxattrib->encrypt > 0) {
485 		u8 *iv = precv_frame->pkt->data + prxattrib->hdrlen;
486 		prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
487 
488 		if (prxattrib->key_index > WEP_KEYS) {
489 			DBG_8723A("prxattrib->key_index(%d) > WEP_KEYS\n",
490 				  prxattrib->key_index);
491 
492 			switch (prxattrib->encrypt) {
493 			case WLAN_CIPHER_SUITE_WEP40:
494 			case WLAN_CIPHER_SUITE_WEP104:
495 				prxattrib->key_index =
496 					psecuritypriv->dot11PrivacyKeyIndex;
497 				break;
498 			case WLAN_CIPHER_SUITE_TKIP:
499 			case WLAN_CIPHER_SUITE_CCMP:
500 			default:
501 				prxattrib->key_index =
502 					psecuritypriv->dot118021XGrpKeyid;
503 				break;
504 			}
505 		}
506 	}
507 
508 	if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0))) {
509 		psecuritypriv->hw_decrypted = 0;
510 		switch (prxattrib->encrypt) {
511 		case WLAN_CIPHER_SUITE_WEP40:
512 		case WLAN_CIPHER_SUITE_WEP104:
513 			rtw_wep_decrypt23a(padapter, precv_frame);
514 			break;
515 		case WLAN_CIPHER_SUITE_TKIP:
516 			res = rtw_tkip_decrypt23a(padapter, precv_frame);
517 			break;
518 		case WLAN_CIPHER_SUITE_CCMP:
519 			res = rtw_aes_decrypt23a(padapter, precv_frame);
520 			break;
521 		default:
522 			break;
523 		}
524 	} else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 &&
525 		   (psecuritypriv->busetkipkey == 1 ||
526 		    prxattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)) {
527 			psecuritypriv->hw_decrypted = 1;
528 	}
529 
530 	if (res == _FAIL) {
531 		rtw_free_recvframe23a(return_packet);
532 		return_packet = NULL;
533 	}
534 
535 
536 
537 	return return_packet;
538 }
539 
540 /* set the security information in the recv_frame */
portctrl(struct rtw_adapter * adapter,struct recv_frame * precv_frame)541 static struct recv_frame *portctrl(struct rtw_adapter *adapter,
542 				   struct recv_frame *precv_frame)
543 {
544 	u8 *psta_addr, *ptr;
545 	uint auth_alg;
546 	struct recv_frame *pfhdr;
547 	struct sta_info *psta;
548 	struct sta_priv *pstapriv ;
549 	struct recv_frame *prtnframe;
550 	u16 ether_type;
551 	u16 eapol_type = ETH_P_PAE;/* for Funia BD's WPA issue */
552 	struct rx_pkt_attrib *pattrib;
553 
554 	pstapriv = &adapter->stapriv;
555 
556 	auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
557 
558 	pfhdr = precv_frame;
559 	pattrib = &pfhdr->attrib;
560 	psta_addr = pattrib->ta;
561 	psta = rtw_get_stainfo23a(pstapriv, psta_addr);
562 
563 	RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
564 		 ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm ="
565 		  "%d\n", adapter->securitypriv.dot11AuthAlgrthm));
566 
567 	if (auth_alg == dot11AuthAlgrthm_8021X) {
568 		/* get ether_type */
569 		ptr = pfhdr->pkt->data + pfhdr->attrib.hdrlen;
570 
571 		ether_type = (ptr[6] << 8) | ptr[7];
572 
573 		if ((psta != NULL) && (psta->ieee8021x_blocked)) {
574 			/* blocked */
575 			/* only accept EAPOL frame */
576 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
577 				 ("########portctrl:psta->ieee8021x_blocked =="
578 				  "1\n"));
579 
580 			if (ether_type == eapol_type) {
581 				prtnframe = precv_frame;
582 			} else {
583 				/* free this frame */
584 				rtw_free_recvframe23a(precv_frame);
585 				prtnframe = NULL;
586 			}
587 		} else {
588 			/* allowed */
589 			/* check decryption status, and decrypt the frame if needed */
590 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
591 				 ("########portctrl:psta->ieee8021x_blocked =="
592 				  "0\n"));
593 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
594 				 ("portctrl:precv_frame->hdr.attrib.privacy ="
595 				  "%x\n", precv_frame->attrib.privacy));
596 
597 			if (pattrib->bdecrypted == 0) {
598 				RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
599 					 ("portctrl:prxstat->decrypted =%x\n",
600 					  pattrib->bdecrypted));
601 			}
602 
603 			prtnframe = precv_frame;
604 			/* check is the EAPOL frame or not (Rekey) */
605 			if (ether_type == eapol_type) {
606 				RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
607 					 ("########portctrl:ether_type == "
608 					  "0x888e\n"));
609 				/* check Rekey */
610 
611 				prtnframe = precv_frame;
612 			} else {
613 				RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
614 					 ("########portctrl:ether_type = 0x%04x"
615 					  "\n", ether_type));
616 			}
617 		}
618 	} else {
619 		prtnframe = precv_frame;
620 	}
621 
622 	return prtnframe;
623 }
624 
625 int recv_decache(struct recv_frame *precv_frame, u8 bretry,
626 		 struct stainfo_rxcache *prxcache);
recv_decache(struct recv_frame * precv_frame,u8 bretry,struct stainfo_rxcache * prxcache)627 int recv_decache(struct recv_frame *precv_frame, u8 bretry,
628 		 struct stainfo_rxcache *prxcache)
629 {
630 	int tid = precv_frame->attrib.priority;
631 
632 	u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) |
633 		(precv_frame->attrib.frag_num & 0xf);
634 
635 
636 
637 	if (tid > 15) {
638 		RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
639 			 ("recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n",
640 			  seq_ctrl, tid));
641 
642 		return _FAIL;
643 	}
644 
645 	if (1) { /* if (bretry) */
646 		if (seq_ctrl == prxcache->tid_rxseq[tid]) {
647 			RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
648 				 ("recv_decache, seq_ctrl = 0x%x, tid = 0x%x, "
649 				  "tid_rxseq = 0x%x\n",
650 				  seq_ctrl, tid, prxcache->tid_rxseq[tid]));
651 
652 			return _FAIL;
653 		}
654 	}
655 
656 	prxcache->tid_rxseq[tid] = seq_ctrl;
657 
658 
659 
660 	return _SUCCESS;
661 }
662 
663 void process23a_pwrbit_data(struct rtw_adapter *padapter,
664 			 struct recv_frame *precv_frame);
process23a_pwrbit_data(struct rtw_adapter * padapter,struct recv_frame * precv_frame)665 void process23a_pwrbit_data(struct rtw_adapter *padapter,
666 			 struct recv_frame *precv_frame)
667 {
668 #ifdef CONFIG_8723AU_AP_MODE
669 	unsigned char pwrbit;
670 	struct sk_buff *skb = precv_frame->pkt;
671 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
672 	struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
673 	struct sta_priv *pstapriv = &padapter->stapriv;
674 	struct sta_info *psta = NULL;
675 
676 	psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
677 
678 	if (psta) {
679 		pwrbit = ieee80211_has_pm(hdr->frame_control);
680 
681 		if (pwrbit) {
682 			if (!(psta->state & WIFI_SLEEP_STATE))
683 				stop_sta_xmit23a(padapter, psta);
684 		} else {
685 			if (psta->state & WIFI_SLEEP_STATE)
686 				wakeup_sta_to_xmit23a(padapter, psta);
687 		}
688 	}
689 
690 #endif
691 }
692 
693 void process_wmmps_data(struct rtw_adapter *padapter,
694 			struct recv_frame *precv_frame);
process_wmmps_data(struct rtw_adapter * padapter,struct recv_frame * precv_frame)695 void process_wmmps_data(struct rtw_adapter *padapter,
696 			struct recv_frame *precv_frame)
697 {
698 #ifdef CONFIG_8723AU_AP_MODE
699 	struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
700 	struct sta_priv *pstapriv = &padapter->stapriv;
701 	struct sta_info *psta = NULL;
702 
703 	psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
704 
705 	if (!psta)
706 		return;
707 
708 
709 	if (!psta->qos_option)
710 		return;
711 
712 	if (!(psta->qos_info & 0xf))
713 		return;
714 
715 	if (psta->state & WIFI_SLEEP_STATE) {
716 		u8 wmmps_ac = 0;
717 
718 		switch (pattrib->priority) {
719 		case 1:
720 		case 2:
721 			wmmps_ac = psta->uapsd_bk & BIT(1);
722 			break;
723 		case 4:
724 		case 5:
725 			wmmps_ac = psta->uapsd_vi & BIT(1);
726 			break;
727 		case 6:
728 		case 7:
729 			wmmps_ac = psta->uapsd_vo & BIT(1);
730 			break;
731 		case 0:
732 		case 3:
733 		default:
734 			wmmps_ac = psta->uapsd_be & BIT(1);
735 			break;
736 		}
737 
738 		if (wmmps_ac) {
739 			if (psta->sleepq_ac_len > 0) {
740 				/* process received triggered frame */
741 				xmit_delivery_enabled_frames23a(padapter, psta);
742 			} else {
743 				/* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */
744 				issue_qos_nulldata23a(padapter, psta->hwaddr,
745 						   (u16)pattrib->priority,
746 						   0, 0);
747 			}
748 		}
749 	}
750 
751 #endif
752 }
753 
count_rx_stats(struct rtw_adapter * padapter,struct recv_frame * prframe,struct sta_info * sta)754 static void count_rx_stats(struct rtw_adapter *padapter,
755 			   struct recv_frame *prframe, struct sta_info *sta)
756 {
757 	int sz;
758 	struct sta_info *psta = NULL;
759 	struct stainfo_stats *pstats = NULL;
760 	struct rx_pkt_attrib *pattrib = & prframe->attrib;
761 	struct recv_priv *precvpriv = &padapter->recvpriv;
762 
763 	sz = prframe->pkt->len;
764 	precvpriv->rx_bytes += sz;
765 
766 	padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
767 
768 	if ((!is_broadcast_ether_addr(pattrib->dst)) &&
769 	    (!is_multicast_ether_addr(pattrib->dst)))
770 		padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
771 
772 	if (sta)
773 		psta = sta;
774 	else
775 		psta = prframe->psta;
776 
777 	if (psta) {
778 		pstats = &psta->sta_stats;
779 
780 		pstats->rx_data_pkts++;
781 		pstats->rx_bytes += sz;
782 	}
783 }
784 
sta2sta_data_frame(struct rtw_adapter * adapter,struct recv_frame * precv_frame,struct sta_info ** psta)785 static int sta2sta_data_frame(struct rtw_adapter *adapter,
786 			      struct recv_frame *precv_frame,
787 			      struct sta_info**psta)
788 {
789 	struct sk_buff *skb = precv_frame->pkt;
790 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
791 	int ret = _SUCCESS;
792 	struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
793 	struct sta_priv *pstapriv = &adapter->stapriv;
794 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
795 	u8 *mybssid  = get_bssid(pmlmepriv);
796 	u8 *myhwaddr = myid(&adapter->eeprompriv);
797 	u8 *sta_addr = NULL;
798 	int bmcast = is_multicast_ether_addr(pattrib->dst);
799 
800 
801 
802 	if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
803 	    check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
804 
805 		/*  filter packets that SA is myself or multicast or broadcast */
806 		if (ether_addr_equal(myhwaddr, pattrib->src)) {
807 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
808 				 (" SA == myself\n"));
809 			ret = _FAIL;
810 			goto exit;
811 		}
812 
813 		if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
814 			ret = _FAIL;
815 			goto exit;
816 		}
817 
818 		if (ether_addr_equal(pattrib->bssid, "\x0\x0\x0\x0\x0\x0") ||
819 		    ether_addr_equal(mybssid, "\x0\x0\x0\x0\x0\x0") ||
820 		    !ether_addr_equal(pattrib->bssid, mybssid)) {
821 			ret = _FAIL;
822 			goto exit;
823 		}
824 
825 		sta_addr = pattrib->src;
826 	} else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
827 		/*  For Station mode, sa and bssid should always be BSSID,
828 		    and DA is my mac-address */
829 		if (!ether_addr_equal(pattrib->bssid, pattrib->src)) {
830 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
831 				 ("bssid != TA under STATION_MODE; drop "
832 				  "pkt\n"));
833 			ret = _FAIL;
834 			goto exit;
835 		}
836 
837 		sta_addr = pattrib->bssid;
838 
839 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
840 		if (bmcast) {
841 			/*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
842 			if (!is_multicast_ether_addr(pattrib->bssid)) {
843 				ret = _FAIL;
844 				goto exit;
845 			}
846 		} else { /*  not mc-frame */
847 			/*  For AP mode, if DA is non-MCAST, then it must
848 			    be BSSID, and bssid == BSSID */
849 			if (!ether_addr_equal(pattrib->bssid, pattrib->dst)) {
850 				ret = _FAIL;
851 				goto exit;
852 			}
853 
854 			sta_addr = pattrib->src;
855 		}
856 	} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
857 		ether_addr_copy(pattrib->dst, hdr->addr1);
858 		ether_addr_copy(pattrib->src, hdr->addr2);
859 		ether_addr_copy(pattrib->bssid, hdr->addr3);
860 		ether_addr_copy(pattrib->ra, pattrib->dst);
861 		ether_addr_copy(pattrib->ta, pattrib->src);
862 
863 		sta_addr = mybssid;
864 	} else {
865 		ret  = _FAIL;
866 	}
867 
868 	if (bmcast)
869 		*psta = rtw_get_bcmc_stainfo23a(adapter);
870 	else
871 		*psta = rtw_get_stainfo23a(pstapriv, sta_addr); /*  get ap_info */
872 
873 	if (*psta == NULL) {
874 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under sta2sta_data_frame ; drop pkt\n"));
875 		ret = _FAIL;
876 		goto exit;
877 	}
878 
879 exit:
880 
881 	return ret;
882 }
883 
884 int ap2sta_data_frame(struct rtw_adapter *adapter,
885 		      struct recv_frame *precv_frame,
886 		      struct sta_info **psta);
ap2sta_data_frame(struct rtw_adapter * adapter,struct recv_frame * precv_frame,struct sta_info ** psta)887 int ap2sta_data_frame(struct rtw_adapter *adapter,
888 		      struct recv_frame *precv_frame,
889 		      struct sta_info **psta)
890 {
891 	struct sk_buff *skb = precv_frame->pkt;
892 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
893 	struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
894 	int ret = _SUCCESS;
895 	struct sta_priv *pstapriv = &adapter->stapriv;
896 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
897 	u8 *mybssid  = get_bssid(pmlmepriv);
898 	u8 *myhwaddr = myid(&adapter->eeprompriv);
899 	int bmcast = is_multicast_ether_addr(pattrib->dst);
900 
901 
902 
903 	if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
904 	    (check_fwstate(pmlmepriv, _FW_LINKED) ||
905 	     check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) {
906 
907 		/* filter packets that SA is myself or multicast or broadcast */
908 		if (ether_addr_equal(myhwaddr, pattrib->src)) {
909 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
910 				 (" SA == myself\n"));
911 			ret = _FAIL;
912 			goto exit;
913 		}
914 
915 		/*  da should be for me */
916 		if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
917 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
918 				(" ap2sta_data_frame:  compare DA fail; DA ="
919 				 MAC_FMT"\n", MAC_ARG(pattrib->dst)));
920 			ret = _FAIL;
921 			goto exit;
922 		}
923 
924 		/*  check BSSID */
925 		if (ether_addr_equal(pattrib->bssid, "\x0\x0\x0\x0\x0\x0") ||
926 		    ether_addr_equal(mybssid, "\x0\x0\x0\x0\x0\x0") ||
927 		    !ether_addr_equal(pattrib->bssid, mybssid)) {
928 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
929 				(" ap2sta_data_frame:  compare BSSID fail ; "
930 				 "BSSID ="MAC_FMT"\n", MAC_ARG(pattrib->bssid)));
931 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
932 				 ("mybssid ="MAC_FMT"\n", MAC_ARG(mybssid)));
933 
934 			if (!bmcast) {
935 				DBG_8723A("issue_deauth23a to the nonassociated "
936 					  "ap =" MAC_FMT " for the reason(7)\n",
937 					  MAC_ARG(pattrib->bssid));
938 				issue_deauth23a(adapter, pattrib->bssid,
939 					     WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
940 			}
941 
942 			ret = _FAIL;
943 			goto exit;
944 		}
945 
946 		if (bmcast)
947 			*psta = rtw_get_bcmc_stainfo23a(adapter);
948 		else
949 			/*  get ap_info */
950 			*psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
951 
952 		if (*psta == NULL) {
953 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
954 				 ("ap2sta: can't get psta under STATION_MODE ;"
955 				  " drop pkt\n"));
956 			ret = _FAIL;
957 			goto exit;
958 		}
959 
960 		if (ieee80211_is_nullfunc(hdr->frame_control)) {
961 			/* No data, will not indicate to upper layer,
962 			   temporily count it here */
963 			count_rx_stats(adapter, precv_frame, *psta);
964 			ret = RTW_RX_HANDLED;
965 			goto exit;
966 		}
967 
968 	} else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
969 		   check_fwstate(pmlmepriv, _FW_LINKED)) {
970 		ether_addr_copy(pattrib->dst, hdr->addr1);
971 		ether_addr_copy(pattrib->src, hdr->addr2);
972 		ether_addr_copy(pattrib->bssid, hdr->addr3);
973 		ether_addr_copy(pattrib->ra, pattrib->dst);
974 		ether_addr_copy(pattrib->ta, pattrib->src);
975 
976 		/*  */
977 		ether_addr_copy(pattrib->bssid,  mybssid);
978 
979 		/*  get sta_info */
980 		*psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
981 		if (*psta == NULL) {
982 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
983 				 ("can't get psta under MP_MODE ; drop pkt\n"));
984 			ret = _FAIL;
985 			goto exit;
986 		}
987 	} else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
988 		/* Special case */
989 		ret = RTW_RX_HANDLED;
990 		goto exit;
991 	} else {
992 		if (ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
993 			*psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
994 			if (*psta == NULL) {
995 				DBG_8723A("issue_deauth23a to the ap =" MAC_FMT
996 					  " for the reason(7)\n",
997 					  MAC_ARG(pattrib->bssid));
998 
999 				issue_deauth23a(adapter, pattrib->bssid,
1000 					     WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1001 			}
1002 		}
1003 
1004 		ret = _FAIL;
1005 	}
1006 
1007 exit:
1008 
1009 
1010 
1011 	return ret;
1012 }
1013 
1014 int sta2ap_data_frame(struct rtw_adapter *adapter,
1015 		      struct recv_frame *precv_frame,
1016 		      struct sta_info **psta);
sta2ap_data_frame(struct rtw_adapter * adapter,struct recv_frame * precv_frame,struct sta_info ** psta)1017 int sta2ap_data_frame(struct rtw_adapter *adapter,
1018 		      struct recv_frame *precv_frame,
1019 		      struct sta_info **psta)
1020 {
1021 	struct sk_buff *skb = precv_frame->pkt;
1022 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1023 	struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
1024 	struct sta_priv *pstapriv = &adapter->stapriv;
1025 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1026 	unsigned char *mybssid = get_bssid(pmlmepriv);
1027 	int ret = _SUCCESS;
1028 
1029 
1030 
1031 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
1032 		/* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */
1033 		if (!ether_addr_equal(pattrib->bssid, mybssid)) {
1034 			ret = _FAIL;
1035 			goto exit;
1036 		}
1037 
1038 		*psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
1039 		if (*psta == NULL) {
1040 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1041 				 ("can't get psta under AP_MODE; drop pkt\n"));
1042 			DBG_8723A("issue_deauth23a to sta =" MAC_FMT
1043 				  " for the reason(7)\n",
1044 				  MAC_ARG(pattrib->src));
1045 
1046 			issue_deauth23a(adapter, pattrib->src,
1047 				     WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1048 
1049 			ret = RTW_RX_HANDLED;
1050 			goto exit;
1051 		}
1052 
1053 		process23a_pwrbit_data(adapter, precv_frame);
1054 
1055 		/* We only get here if it's a data frame, so no need to
1056 		 * confirm data frame type first */
1057 		if (ieee80211_is_data_qos(hdr->frame_control))
1058 			process_wmmps_data(adapter, precv_frame);
1059 
1060 		if (ieee80211_is_nullfunc(hdr->frame_control)) {
1061 			/* No data, will not indicate to upper layer,
1062 			   temporily count it here */
1063 			count_rx_stats(adapter, precv_frame, *psta);
1064 			ret = RTW_RX_HANDLED;
1065 			goto exit;
1066 		}
1067 	} else {
1068 		u8 *myhwaddr = myid(&adapter->eeprompriv);
1069 		if (!ether_addr_equal(pattrib->ra, myhwaddr)) {
1070 			ret = RTW_RX_HANDLED;
1071 			goto exit;
1072 		}
1073 		DBG_8723A("issue_deauth23a to sta =" MAC_FMT " for the reason(7)\n",
1074 			  MAC_ARG(pattrib->src));
1075 		issue_deauth23a(adapter, pattrib->src,
1076 			     WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1077 		ret = RTW_RX_HANDLED;
1078 		goto exit;
1079 	}
1080 
1081 exit:
1082 
1083 
1084 
1085 	return ret;
1086 }
1087 
validate_recv_ctrl_frame(struct rtw_adapter * padapter,struct recv_frame * precv_frame)1088 static int validate_recv_ctrl_frame(struct rtw_adapter *padapter,
1089 				    struct recv_frame *precv_frame)
1090 {
1091 #ifdef CONFIG_8723AU_AP_MODE
1092 	struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
1093 	struct sta_priv *pstapriv = &padapter->stapriv;
1094 	struct sk_buff *skb = precv_frame->pkt;
1095 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1096 
1097 	if (!ieee80211_is_ctl(hdr->frame_control))
1098 		return _FAIL;
1099 
1100 	/* receive the frames that ra(a1) is my address */
1101 	if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv)))
1102 		return _FAIL;
1103 
1104 	/* only handle ps-poll */
1105 	if (ieee80211_is_pspoll(hdr->frame_control)) {
1106 		struct ieee80211_pspoll *psp = (struct ieee80211_pspoll *)hdr;
1107 		u16 aid;
1108 		u8 wmmps_ac = 0;
1109 		struct sta_info *psta = NULL;
1110 
1111 		aid = le16_to_cpu(psp->aid) & 0x3fff;
1112 		psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
1113 
1114 		if (!psta || psta->aid != aid)
1115 			return _FAIL;
1116 
1117 		/* for rx pkt statistics */
1118 		psta->sta_stats.rx_ctrl_pkts++;
1119 
1120 		switch (pattrib->priority) {
1121 		case 1:
1122 		case 2:
1123 			wmmps_ac = psta->uapsd_bk & BIT(0);
1124 			break;
1125 		case 4:
1126 		case 5:
1127 			wmmps_ac = psta->uapsd_vi & BIT(0);
1128 			break;
1129 		case 6:
1130 		case 7:
1131 			wmmps_ac = psta->uapsd_vo & BIT(0);
1132 			break;
1133 		case 0:
1134 		case 3:
1135 		default:
1136 			wmmps_ac = psta->uapsd_be & BIT(0);
1137 			break;
1138 		}
1139 
1140 		if (wmmps_ac)
1141 			return _FAIL;
1142 
1143 		if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1144 			DBG_8723A("%s alive check-rx ps-poll\n", __func__);
1145 			psta->expire_to = pstapriv->expire_to;
1146 			psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1147 		}
1148 
1149 		if ((psta->state & WIFI_SLEEP_STATE) &&
1150 		    (pstapriv->sta_dz_bitmap & CHKBIT(psta->aid))) {
1151 			struct list_head *xmitframe_plist, *xmitframe_phead;
1152 			struct xmit_frame *pxmitframe;
1153 			struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1154 
1155 			spin_lock_bh(&pxmitpriv->lock);
1156 
1157 			xmitframe_phead = get_list_head(&psta->sleep_q);
1158 			xmitframe_plist = xmitframe_phead->next;
1159 
1160 			if (!list_empty(xmitframe_phead)) {
1161 				pxmitframe = container_of(xmitframe_plist,
1162 							  struct xmit_frame,
1163 							  list);
1164 
1165 				xmitframe_plist = xmitframe_plist->next;
1166 
1167 				list_del_init(&pxmitframe->list);
1168 
1169 				psta->sleepq_len--;
1170 
1171 				if (psta->sleepq_len>0)
1172 					pxmitframe->attrib.mdata = 1;
1173 				else
1174 					pxmitframe->attrib.mdata = 0;
1175 
1176 				pxmitframe->attrib.triggered = 1;
1177 
1178 	                        /* DBG_8723A("handling ps-poll, q_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1179 
1180 				rtl8723au_hal_xmitframe_enqueue(padapter,
1181 								pxmitframe);
1182 
1183 				if (psta->sleepq_len == 0) {
1184 					pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
1185 
1186 					/* DBG_8723A("after handling ps-poll, tim =%x\n", pstapriv->tim_bitmap); */
1187 
1188 					/* update BCN for TIM IE */
1189 					/* update_BCNTIM(padapter); */
1190 					update_beacon23a(padapter, WLAN_EID_TIM,
1191 							 NULL, false);
1192 				}
1193 
1194 				/* spin_unlock_bh(&psta->sleep_q.lock); */
1195 				spin_unlock_bh(&pxmitpriv->lock);
1196 
1197 			} else {
1198 				/* spin_unlock_bh(&psta->sleep_q.lock); */
1199 				spin_unlock_bh(&pxmitpriv->lock);
1200 
1201 				/* DBG_8723A("no buffered packets to xmit\n"); */
1202 				if (pstapriv->tim_bitmap & CHKBIT(psta->aid)) {
1203 					if (psta->sleepq_len == 0) {
1204 						DBG_8723A("no buffered packets "
1205 							  "to xmit\n");
1206 
1207 						/* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1208 						issue_nulldata23a(padapter,
1209 							       psta->hwaddr,
1210 							       0, 0, 0);
1211 					} else {
1212 						DBG_8723A("error!psta->sleepq"
1213 							  "_len =%d\n",
1214 							  psta->sleepq_len);
1215 						psta->sleepq_len = 0;
1216 					}
1217 
1218 					pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
1219 
1220 					/* update BCN for TIM IE */
1221 					/* update_BCNTIM(padapter); */
1222 					update_beacon23a(padapter, WLAN_EID_TIM,
1223 							 NULL, false);
1224 				}
1225 			}
1226 		}
1227 	}
1228 
1229 #endif
1230 	return _FAIL;
1231 }
1232 
1233 struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1234 					struct recv_frame *precv_frame);
validate_recv_mgnt_frame(struct rtw_adapter * padapter,struct recv_frame * precv_frame)1235 static int validate_recv_mgnt_frame(struct rtw_adapter *padapter,
1236 				    struct recv_frame *precv_frame)
1237 {
1238 	struct sta_info *psta;
1239 	struct sk_buff *skb;
1240 	struct ieee80211_hdr *hdr;
1241 	/* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */
1242 
1243 	RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1244 		 ("+validate_recv_mgnt_frame\n"));
1245 
1246 	precv_frame = recvframe_chk_defrag23a(padapter, precv_frame);
1247 	if (precv_frame == NULL) {
1248 		RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1249 			 ("%s: fragment packet\n", __func__));
1250 		return _SUCCESS;
1251 	}
1252 
1253 	skb = precv_frame->pkt;
1254 	hdr = (struct ieee80211_hdr *) skb->data;
1255 
1256 		/* for rx pkt statistics */
1257 	psta = rtw_get_stainfo23a(&padapter->stapriv, hdr->addr2);
1258 	if (psta) {
1259 		psta->sta_stats.rx_mgnt_pkts++;
1260 
1261 		if (ieee80211_is_beacon(hdr->frame_control))
1262 			psta->sta_stats.rx_beacon_pkts++;
1263 		else if (ieee80211_is_probe_req(hdr->frame_control))
1264 			psta->sta_stats.rx_probereq_pkts++;
1265 		else if (ieee80211_is_probe_resp(hdr->frame_control)) {
1266 			if (ether_addr_equal(padapter->eeprompriv.mac_addr,
1267 				    hdr->addr1))
1268 				psta->sta_stats.rx_probersp_pkts++;
1269 			else if (is_broadcast_ether_addr(hdr->addr1) ||
1270 				 is_multicast_ether_addr(hdr->addr1))
1271 				psta->sta_stats.rx_probersp_bm_pkts++;
1272 			else
1273 				psta->sta_stats.rx_probersp_uo_pkts++;
1274 		}
1275 	}
1276 
1277 	mgt_dispatcher23a(padapter, precv_frame);
1278 
1279 	return _SUCCESS;
1280 }
1281 
validate_recv_data_frame(struct rtw_adapter * adapter,struct recv_frame * precv_frame)1282 static int validate_recv_data_frame(struct rtw_adapter *adapter,
1283 				    struct recv_frame *precv_frame)
1284 {
1285 	u8 bretry;
1286 	u8 *psa, *pda;
1287 	struct sta_info *psta = NULL;
1288 	struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
1289 	struct security_priv *psecuritypriv = &adapter->securitypriv;
1290 	int ret = _SUCCESS;
1291 	struct sk_buff *skb = precv_frame->pkt;
1292 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1293 
1294 
1295 
1296 	bretry = ieee80211_has_retry(hdr->frame_control);
1297 	pda = ieee80211_get_DA(hdr);
1298 	psa = ieee80211_get_SA(hdr);
1299 
1300 	ether_addr_copy(pattrib->dst, pda);
1301 	ether_addr_copy(pattrib->src, psa);
1302 
1303 	switch (hdr->frame_control &
1304 		cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
1305 	case cpu_to_le16(0):
1306 		ether_addr_copy(pattrib->bssid, hdr->addr3);
1307 		ether_addr_copy(pattrib->ra, pda);
1308 		ether_addr_copy(pattrib->ta, psa);
1309 		ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1310 		break;
1311 
1312 	case cpu_to_le16(IEEE80211_FCTL_FROMDS):
1313 		ether_addr_copy(pattrib->bssid, hdr->addr2);
1314 		ether_addr_copy(pattrib->ra, pda);
1315 		ether_addr_copy(pattrib->ta, hdr->addr2);
1316 		ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1317 		break;
1318 
1319 	case cpu_to_le16(IEEE80211_FCTL_TODS):
1320 		ether_addr_copy(pattrib->bssid, hdr->addr1);
1321 		ether_addr_copy(pattrib->ra, hdr->addr1);
1322 		ether_addr_copy(pattrib->ta, psa);
1323 		ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1324 		break;
1325 
1326 	case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
1327 		/*
1328 		 * There is no BSSID in this case, but the driver has been
1329 		 * using addr1 so far, so keep it for now.
1330 		 */
1331 		ether_addr_copy(pattrib->bssid, hdr->addr1);
1332 		ether_addr_copy(pattrib->ra, hdr->addr1);
1333 		ether_addr_copy(pattrib->ta, hdr->addr2);
1334 		ret = _FAIL;
1335 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n"));
1336 		break;
1337 	}
1338 
1339 	if ((ret == _FAIL) || (ret == RTW_RX_HANDLED))
1340 		goto exit;
1341 
1342 	if (!psta) {
1343 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1344 			 (" after to_fr_ds_chk; psta == NULL\n"));
1345 		ret = _FAIL;
1346 		goto exit;
1347 	}
1348 
1349 	/* psta->rssi = prxcmd->rssi; */
1350 	/* psta->signal_quality = prxcmd->sq; */
1351 	precv_frame->psta = psta;
1352 
1353 	pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
1354 	if (ieee80211_has_a4(hdr->frame_control))
1355 		pattrib->hdrlen += ETH_ALEN;
1356 
1357 	/* parsing QC field */
1358 	if (pattrib->qos == 1) {
1359 		__le16 *qptr = (__le16 *)ieee80211_get_qos_ctl(hdr);
1360 		u16 qos_ctrl = le16_to_cpu(*qptr);
1361 
1362 		pattrib->priority = qos_ctrl & IEEE80211_QOS_CTL_TID_MASK;
1363 		pattrib->ack_policy = (qos_ctrl >> 5) & 3;
1364 		pattrib->amsdu =
1365 			(qos_ctrl & IEEE80211_QOS_CTL_A_MSDU_PRESENT) >> 7;
1366 		pattrib->hdrlen += IEEE80211_QOS_CTL_LEN;
1367 
1368 		if (pattrib->priority != 0 && pattrib->priority != 3) {
1369 			adapter->recvpriv.bIsAnyNonBEPkts = true;
1370 		}
1371 	} else {
1372 		pattrib->priority = 0;
1373 		pattrib->ack_policy = 0;
1374 		pattrib->amsdu = 0;
1375 	}
1376 
1377 	if (pattrib->order) { /* HT-CTRL 11n */
1378 		pattrib->hdrlen += 4;
1379 	}
1380 
1381 	precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1382 
1383 	/*  decache, drop duplicate recv packets */
1384 	if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
1385 	    _FAIL) {
1386 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1387 			 ("decache : drop pkt\n"));
1388 		ret = _FAIL;
1389 		goto exit;
1390 	}
1391 
1392 	if (pattrib->privacy) {
1393 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1394 			 ("validate_recv_data_frame:pattrib->privacy =%x\n",
1395 			 pattrib->privacy));
1396 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1397 			 ("\n ^^^^^^^^^^^is_multicast_ether_addr"
1398 			  "(pattrib->ra(0x%02x)) =%d^^^^^^^^^^^^^^^6\n",
1399 			  pattrib->ra[0],
1400 			  is_multicast_ether_addr(pattrib->ra)));
1401 
1402 		GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
1403 			       is_multicast_ether_addr(pattrib->ra));
1404 
1405 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1406 			 ("\n pattrib->encrypt =%d\n", pattrib->encrypt));
1407 
1408 		switch (pattrib->encrypt)
1409 		{
1410 		case WLAN_CIPHER_SUITE_WEP40:
1411 		case WLAN_CIPHER_SUITE_WEP104:
1412 			pattrib->iv_len = IEEE80211_WEP_IV_LEN;
1413 			pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
1414 			break;
1415 		case WLAN_CIPHER_SUITE_TKIP:
1416 			pattrib->iv_len = IEEE80211_TKIP_IV_LEN;
1417 			pattrib->icv_len = IEEE80211_TKIP_ICV_LEN;
1418 			break;
1419 		case WLAN_CIPHER_SUITE_CCMP:
1420 			pattrib->iv_len = IEEE80211_CCMP_HDR_LEN;
1421 			pattrib->icv_len = IEEE80211_CCMP_MIC_LEN;
1422 			break;
1423 		default:
1424 			pattrib->iv_len = 0;
1425 			pattrib->icv_len = 0;
1426 			break;
1427 		}
1428 	} else {
1429 		pattrib->encrypt = 0;
1430 		pattrib->iv_len = 0;
1431 		pattrib->icv_len = 0;
1432 	}
1433 
1434 exit:
1435 
1436 
1437 
1438 	return ret;
1439 }
1440 
dump_rx_pkt(struct sk_buff * skb,u16 type,int level)1441 static void dump_rx_pkt(struct sk_buff *skb, u16 type, int level)
1442 {
1443 	int i;
1444 	u8 *ptr;
1445 
1446 	if ((level == 1) ||
1447 	    ((level == 2) && (type == IEEE80211_FTYPE_MGMT)) ||
1448 	    ((level == 3) && (type == IEEE80211_FTYPE_DATA))) {
1449 
1450 		ptr = skb->data;
1451 
1452 		DBG_8723A("#############################\n");
1453 
1454 		for (i = 0; i < 64; i = i + 8)
1455 			DBG_8723A("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n",
1456 				  *(ptr + i), *(ptr + i + 1), *(ptr + i + 2),
1457 				  *(ptr + i + 3), *(ptr + i + 4),
1458 				  *(ptr + i + 5), *(ptr + i + 6),
1459 				  *(ptr + i + 7));
1460 		DBG_8723A("#############################\n");
1461 	}
1462 }
1463 
validate_recv_frame(struct rtw_adapter * adapter,struct recv_frame * precv_frame)1464 static int validate_recv_frame(struct rtw_adapter *adapter,
1465 			       struct recv_frame *precv_frame)
1466 {
1467 	/* shall check frame subtype, to / from ds, da, bssid */
1468 
1469 	/* then call check if rx seq/frag. duplicated. */
1470 	u8 type;
1471 	u8 subtype;
1472 	int retval = _SUCCESS;
1473 	struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
1474 	struct sk_buff *skb = precv_frame->pkt;
1475 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1476 	u8 ver;
1477 	u8 bDumpRxPkt;
1478 	u16 seq_ctrl, fctl;
1479 
1480 	fctl = le16_to_cpu(hdr->frame_control);
1481 	ver = fctl & IEEE80211_FCTL_VERS;
1482 	type = fctl & IEEE80211_FCTL_FTYPE;
1483 	subtype = fctl & IEEE80211_FCTL_STYPE;
1484 
1485 	/* add version chk */
1486 	if (ver != 0) {
1487 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1488 			 ("validate_recv_data_frame fail! (ver!= 0)\n"));
1489 		retval = _FAIL;
1490 		goto exit;
1491 	}
1492 
1493 	seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
1494 	pattrib->frag_num = seq_ctrl & IEEE80211_SCTL_FRAG;
1495 	pattrib->seq_num = seq_ctrl >> 4;
1496 
1497 	pattrib->pw_save = ieee80211_has_pm(hdr->frame_control);
1498 	pattrib->mfrag = ieee80211_has_morefrags(hdr->frame_control);
1499 	pattrib->mdata = ieee80211_has_moredata(hdr->frame_control);
1500 	pattrib->privacy = ieee80211_has_protected(hdr->frame_control);
1501 	pattrib->order = ieee80211_has_order(hdr->frame_control);
1502 
1503 	GetHalDefVar8192CUsb(adapter, HAL_DEF_DBG_DUMP_RXPKT, &bDumpRxPkt);
1504 
1505 	if (unlikely(bDumpRxPkt == 1))
1506 		dump_rx_pkt(skb, type, bDumpRxPkt);
1507 
1508 	switch (type)
1509 	{
1510 	case IEEE80211_FTYPE_MGMT:
1511 		retval = validate_recv_mgnt_frame(adapter, precv_frame);
1512 		if (retval == _FAIL) {
1513 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1514 				 ("validate_recv_mgnt_frame fail\n"));
1515 		}
1516 		retval = _FAIL; /*  only data frame return _SUCCESS */
1517 		break;
1518 	case IEEE80211_FTYPE_CTL:
1519 		retval = validate_recv_ctrl_frame(adapter, precv_frame);
1520 		if (retval == _FAIL) {
1521 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1522 				 ("validate_recv_ctrl_frame fail\n"));
1523 		}
1524 		retval = _FAIL; /*  only data frame return _SUCCESS */
1525 		break;
1526 	case IEEE80211_FTYPE_DATA:
1527 		rtw_led_control(adapter, LED_CTL_RX);
1528 		pattrib->qos = (subtype & IEEE80211_STYPE_QOS_DATA) ? 1 : 0;
1529 		retval = validate_recv_data_frame(adapter, precv_frame);
1530 		if (retval == _FAIL) {
1531 			struct recv_priv *precvpriv = &adapter->recvpriv;
1532 			/* RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail\n")); */
1533 			precvpriv->rx_drop++;
1534 		}
1535 		break;
1536 	default:
1537 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1538 			 ("validate_recv_data_frame fail! type = 0x%x\n", type));
1539 		retval = _FAIL;
1540 		break;
1541 	}
1542 
1543 exit:
1544 	return retval;
1545 }
1546 
1547 /* remove the wlanhdr and add the eth_hdr */
1548 
wlanhdr_to_ethhdr(struct recv_frame * precvframe)1549 static int wlanhdr_to_ethhdr (struct recv_frame *precvframe)
1550 {
1551 	u16	eth_type, len, hdrlen;
1552 	u8	bsnaphdr;
1553 	u8	*psnap;
1554 
1555 	int ret = _SUCCESS;
1556 	struct rtw_adapter *adapter = precvframe->adapter;
1557 	struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1558 
1559 	struct sk_buff *skb = precvframe->pkt;
1560 	u8 *ptr;
1561 	struct rx_pkt_attrib *pattrib = &precvframe->attrib;
1562 
1563 
1564 
1565 	ptr = skb->data;
1566 	hdrlen = pattrib->hdrlen;
1567 	psnap = ptr + hdrlen;
1568 	eth_type = (psnap[6] << 8) | psnap[7];
1569 	/* convert hdr + possible LLC headers into Ethernet header */
1570 	/* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
1571 	if ((ether_addr_equal(psnap, rfc1042_header) &&
1572 	     eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
1573 	    ether_addr_equal(psnap, bridge_tunnel_header)) {
1574 		/* remove RFC1042 or Bridge-Tunnel encapsulation
1575 		   and replace EtherType */
1576 		bsnaphdr = true;
1577 		hdrlen += SNAP_SIZE;
1578 	} else {
1579 		/* Leave Ethernet header part of hdr and full payload */
1580 		bsnaphdr = false;
1581 		eth_type = (psnap[0] << 8) | psnap[1];
1582 	}
1583 
1584 	len = skb->len - hdrlen;
1585 
1586 	RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1587 		 ("\n === pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n\n",
1588 		  pattrib->hdrlen,  pattrib->iv_len));
1589 
1590 	pattrib->eth_type = eth_type;
1591 	if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
1592 		ptr += hdrlen;
1593 		*ptr = 0x87;
1594 		*(ptr + 1) = 0x12;
1595 
1596 		eth_type = 0x8712;
1597 		/*  append rx status for mp test packets */
1598 
1599 		ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) + 2) - 24);
1600 		memcpy(ptr, skb->head, 24);
1601 		ptr += 24;
1602 	} else {
1603 		ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) +
1604 				     (bsnaphdr ? 2:0)));
1605 	}
1606 
1607 	ether_addr_copy(ptr, pattrib->dst);
1608 	ether_addr_copy(ptr + ETH_ALEN, pattrib->src);
1609 
1610 	if (!bsnaphdr) {
1611 		len = htons(len);
1612 		memcpy(ptr + 12, &len, 2);
1613 	}
1614 
1615 
1616 	return ret;
1617 }
1618 
1619 /* perform defrag */
1620 struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1621 				    struct rtw_queue *defrag_q);
recvframe_defrag(struct rtw_adapter * adapter,struct rtw_queue * defrag_q)1622 struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1623 				    struct rtw_queue *defrag_q)
1624 {
1625 	struct list_head *plist, *phead, *ptmp;
1626 	u8	*data, wlanhdr_offset;
1627 	u8	curfragnum;
1628 	struct recv_frame *pnfhdr;
1629 	struct recv_frame *prframe, *pnextrframe;
1630 	struct rtw_queue	*pfree_recv_queue;
1631 	struct sk_buff *skb;
1632 
1633 
1634 
1635 	curfragnum = 0;
1636 	pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
1637 
1638 	phead = get_list_head(defrag_q);
1639 	plist = phead->next;
1640 	prframe = container_of(plist, struct recv_frame, list);
1641 	list_del_init(&prframe->list);
1642 	skb = prframe->pkt;
1643 
1644 	if (curfragnum != prframe->attrib.frag_num) {
1645 		/* the first fragment number must be 0 */
1646 		/* free the whole queue */
1647 		rtw_free_recvframe23a(prframe);
1648 		rtw_free_recvframe23a_queue(defrag_q);
1649 
1650 		return NULL;
1651 	}
1652 
1653 	curfragnum++;
1654 
1655 	phead = get_list_head(defrag_q);
1656 
1657 	data = prframe->pkt->data;
1658 
1659 	list_for_each_safe(plist, ptmp, phead) {
1660 		pnfhdr = container_of(plist, struct recv_frame, list);
1661 		pnextrframe = (struct recv_frame *)pnfhdr;
1662 		/* check the fragment sequence  (2nd ~n fragment frame) */
1663 
1664 		if (curfragnum != pnfhdr->attrib.frag_num) {
1665 			/* the fragment number must be increasing
1666 			   (after decache) */
1667 			/* release the defrag_q & prframe */
1668 			rtw_free_recvframe23a(prframe);
1669 			rtw_free_recvframe23a_queue(defrag_q);
1670 			return NULL;
1671 		}
1672 
1673 		curfragnum++;
1674 
1675 		/* copy the 2nd~n fragment frame's payload to the
1676 		   first fragment */
1677 		/* get the 2nd~last fragment frame's payload */
1678 
1679 		wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1680 
1681 		skb_pull(pnfhdr->pkt, wlanhdr_offset);
1682 
1683 		/* append  to first fragment frame's tail
1684 		   (if privacy frame, pull the ICV) */
1685 
1686 		skb_trim(skb, skb->len - prframe->attrib.icv_len);
1687 
1688 		memcpy(skb_tail_pointer(skb), pnfhdr->pkt->data,
1689 		       pnfhdr->pkt->len);
1690 
1691 		skb_put(skb, pnfhdr->pkt->len);
1692 
1693 		prframe->attrib.icv_len = pnfhdr->attrib.icv_len;
1694 	};
1695 
1696 	/* free the defrag_q queue and return the prframe */
1697 	rtw_free_recvframe23a_queue(defrag_q);
1698 
1699 	RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1700 		 ("Performance defrag!!!!!\n"));
1701 
1702 
1703 
1704 	return prframe;
1705 }
1706 
1707 /* check if need to defrag, if needed queue the frame to defrag_q */
recvframe_chk_defrag23a(struct rtw_adapter * padapter,struct recv_frame * precv_frame)1708 struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1709 					struct recv_frame *precv_frame)
1710 {
1711 	u8	ismfrag;
1712 	u8	fragnum;
1713 	u8	*psta_addr;
1714 	struct recv_frame *pfhdr;
1715 	struct sta_info *psta;
1716 	struct sta_priv *pstapriv;
1717 	struct list_head *phead;
1718 	struct recv_frame *prtnframe = NULL;
1719 	struct rtw_queue *pfree_recv_queue, *pdefrag_q;
1720 
1721 
1722 
1723 	pstapriv = &padapter->stapriv;
1724 
1725 	pfhdr = precv_frame;
1726 
1727 	pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1728 
1729 	/* need to define struct of wlan header frame ctrl */
1730 	ismfrag = pfhdr->attrib.mfrag;
1731 	fragnum = pfhdr->attrib.frag_num;
1732 
1733 	psta_addr = pfhdr->attrib.ta;
1734 	psta = rtw_get_stainfo23a(pstapriv, psta_addr);
1735 	if (!psta) {
1736 		struct ieee80211_hdr *hdr =
1737 			(struct ieee80211_hdr *) pfhdr->pkt->data;
1738 		if (!ieee80211_is_data(hdr->frame_control)) {
1739 			psta = rtw_get_bcmc_stainfo23a(padapter);
1740 			pdefrag_q = &psta->sta_recvpriv.defrag_q;
1741 		} else
1742 			pdefrag_q = NULL;
1743 	} else
1744 		pdefrag_q = &psta->sta_recvpriv.defrag_q;
1745 
1746 	if ((ismfrag == 0) && (fragnum == 0)) {
1747 		prtnframe = precv_frame;/* isn't a fragment frame */
1748 	}
1749 
1750 	if (ismfrag == 1) {
1751 		/* 0~(n-1) fragment frame */
1752 		/* enqueue to defraf_g */
1753 		if (pdefrag_q != NULL) {
1754 			if (fragnum == 0) {
1755 				/* the first fragment */
1756 				if (!list_empty(&pdefrag_q->queue)) {
1757 					/* free current defrag_q */
1758 					rtw_free_recvframe23a_queue(pdefrag_q);
1759 				}
1760 			}
1761 
1762 			/* Then enqueue the 0~(n-1) fragment into the
1763 			   defrag_q */
1764 
1765 			/* spin_lock(&pdefrag_q->lock); */
1766 			phead = get_list_head(pdefrag_q);
1767 			list_add_tail(&pfhdr->list, phead);
1768 			/* spin_unlock(&pdefrag_q->lock); */
1769 
1770 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1771 				 ("Enqueuq: ismfrag = %d, fragnum = %d\n",
1772 				  ismfrag, fragnum));
1773 
1774 			prtnframe = NULL;
1775 
1776 		} else {
1777 			/* can't find this ta's defrag_queue,
1778 			   so free this recv_frame */
1779 			rtw_free_recvframe23a(precv_frame);
1780 			prtnframe = NULL;
1781 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1782 				 ("Free because pdefrag_q == NULL: ismfrag = "
1783 				  "%d, fragnum = %d\n", ismfrag, fragnum));
1784 		}
1785 	}
1786 
1787 	if ((ismfrag == 0) && (fragnum != 0)) {
1788 		/* the last fragment frame */
1789 		/* enqueue the last fragment */
1790 		if (pdefrag_q != NULL) {
1791 			/* spin_lock(&pdefrag_q->lock); */
1792 			phead = get_list_head(pdefrag_q);
1793 			list_add_tail(&pfhdr->list, phead);
1794 			/* spin_unlock(&pdefrag_q->lock); */
1795 
1796 			/* call recvframe_defrag to defrag */
1797 			RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1798 				 ("defrag: ismfrag = %d, fragnum = %d\n",
1799 				  ismfrag, fragnum));
1800 			precv_frame = recvframe_defrag(padapter, pdefrag_q);
1801 			prtnframe = precv_frame;
1802 		} else {
1803 			/* can't find this ta's defrag_queue,
1804 			   so free this recv_frame */
1805 			rtw_free_recvframe23a(precv_frame);
1806 			prtnframe = NULL;
1807 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1808 				 ("Free because pdefrag_q == NULL: ismfrag = "
1809 				  "%d, fragnum = %d\n", ismfrag, fragnum));
1810 		}
1811 
1812 	}
1813 
1814 	if ((prtnframe != NULL) && (prtnframe->attrib.privacy))	{
1815 		/* after defrag we must check tkip mic code */
1816 		if (recvframe_chkmic(padapter,  prtnframe) == _FAIL) {
1817 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1818 				 ("recvframe_chkmic(padapter,  prtnframe) =="
1819 				  "_FAIL\n"));
1820 			rtw_free_recvframe23a(prtnframe);
1821 			prtnframe = NULL;
1822 		}
1823 	}
1824 
1825 
1826 
1827 	return prtnframe;
1828 }
1829 
1830 int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe);
amsdu_to_msdu(struct rtw_adapter * padapter,struct recv_frame * prframe)1831 int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe)
1832 {
1833 	struct rx_pkt_attrib *pattrib;
1834 	struct sk_buff *skb, *sub_skb;
1835 	struct sk_buff_head skb_list;
1836 
1837 	pattrib = &prframe->attrib;
1838 
1839 	skb = prframe->pkt;
1840 	skb_pull(skb, prframe->attrib.hdrlen);
1841 	__skb_queue_head_init(&skb_list);
1842 
1843 	ieee80211_amsdu_to_8023s(skb, &skb_list, NULL, 0, 0, false);
1844 
1845 	while (!skb_queue_empty(&skb_list)) {
1846 		sub_skb = __skb_dequeue(&skb_list);
1847 
1848 		sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
1849 		sub_skb->dev = padapter->pnetdev;
1850 
1851 		sub_skb->ip_summed = CHECKSUM_NONE;
1852 
1853 		netif_rx(sub_skb);
1854 	}
1855 
1856 	prframe->pkt = NULL;
1857 	rtw_free_recvframe23a(prframe);
1858 	return _SUCCESS;
1859 }
1860 
1861 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
check_indicate_seq(struct recv_reorder_ctrl * preorder_ctrl,u16 seq_num)1862 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
1863 {
1864 	u8	wsize = preorder_ctrl->wsize_b;
1865 	u16	wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;
1866 
1867 	/*  Rx Reorder initialize condition. */
1868 	if (preorder_ctrl->indicate_seq == 0xFFFF)
1869 		preorder_ctrl->indicate_seq = seq_num;
1870 
1871 	/*  Drop out the packet which SeqNum is smaller than WinStart */
1872 	if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
1873 		return false;
1874 
1875 	/*  */
1876 	/*  Sliding window manipulation. Conditions includes: */
1877 	/*  1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
1878 	/*  2. Incoming SeqNum is larger than the WinEnd => Window shift N */
1879 	/*  */
1880 	if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
1881 		preorder_ctrl->indicate_seq =
1882 			(preorder_ctrl->indicate_seq + 1) & 0xFFF;
1883 	} else if (SN_LESS(wend, seq_num)) {
1884 		/*  boundary situation, when seq_num cross 0xFFF */
1885 		if (seq_num >= (wsize - 1))
1886 			preorder_ctrl->indicate_seq = seq_num + 1 -wsize;
1887 		else
1888 			preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
1889 	}
1890 	return true;
1891 }
1892 
enqueue_reorder_recvframe23a(struct recv_reorder_ctrl * preorder_ctrl,struct recv_frame * prframe)1893 static int enqueue_reorder_recvframe23a(struct recv_reorder_ctrl *preorder_ctrl,
1894 					struct recv_frame *prframe)
1895 {
1896 	struct rx_pkt_attrib *pattrib = &prframe->attrib;
1897 	struct rtw_queue *ppending_recvframe_queue;
1898 	struct list_head *phead, *plist, *ptmp;
1899 	struct recv_frame *hdr;
1900 	struct rx_pkt_attrib *pnextattrib;
1901 
1902 	ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1903 	/* DbgPrint("+enqueue_reorder_recvframe23a()\n"); */
1904 
1905 	/* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1906 	/* spin_lock_ex(&ppending_recvframe_queue->lock); */
1907 
1908 	phead = get_list_head(ppending_recvframe_queue);
1909 
1910 	list_for_each_safe(plist, ptmp, phead) {
1911 		hdr = container_of(plist, struct recv_frame, list);
1912 		pnextattrib = &hdr->attrib;
1913 
1914 		if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) {
1915 			continue;
1916 		} else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
1917 			/* Duplicate entry is found!! Do not insert current entry. */
1918 			/* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
1919 
1920 			/* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1921 			return false;
1922 		} else {
1923 			break;
1924 		}
1925 
1926 		/* DbgPrint("enqueue_reorder_recvframe23a():while\n"); */
1927 	}
1928 
1929 	/* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1930 	/* spin_lock_ex(&ppending_recvframe_queue->lock); */
1931 
1932 	list_del_init(&prframe->list);
1933 
1934 	list_add_tail(&prframe->list, plist);
1935 
1936 	/* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1937 	/* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1938 
1939 	/* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */
1940 	return true;
1941 }
1942 
1943 int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1944 			       struct recv_reorder_ctrl *preorder_ctrl,
1945 			       int bforced);
recv_indicatepkts_in_order(struct rtw_adapter * padapter,struct recv_reorder_ctrl * preorder_ctrl,int bforced)1946 int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1947 			       struct recv_reorder_ctrl *preorder_ctrl,
1948 			       int bforced)
1949 {
1950 	/* u8 bcancelled; */
1951 	struct list_head *phead, *plist;
1952 	struct recv_frame *prframe;
1953 	struct rx_pkt_attrib *pattrib;
1954 	/* u8 index = 0; */
1955 	int bPktInBuf = false;
1956 	struct recv_priv *precvpriv;
1957 	struct rtw_queue *ppending_recvframe_queue;
1958 
1959 	precvpriv = &padapter->recvpriv;
1960 	ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1961 	/* DbgPrint("+recv_indicatepkts_in_order\n"); */
1962 
1963 	/* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1964 	/* spin_lock_ex(&ppending_recvframe_queue->lock); */
1965 
1966 	phead =	get_list_head(ppending_recvframe_queue);
1967 	plist = phead->next;
1968 
1969 	/*  Handling some condition for forced indicate case. */
1970 	if (bforced) {
1971 		if (list_empty(phead)) {
1972 			/*  spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1973 			/* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1974 			return true;
1975 		}
1976 
1977 		prframe = container_of(plist, struct recv_frame, list);
1978 		pattrib = &prframe->attrib;
1979 		preorder_ctrl->indicate_seq = pattrib->seq_num;
1980 	}
1981 
1982 	/*  Prepare indication list and indication. */
1983 	/*  Check if there is any packet need indicate. */
1984 	while (!list_empty(phead)) {
1985 
1986 		prframe = container_of(plist, struct recv_frame, list);
1987 		pattrib = &prframe->attrib;
1988 
1989 		if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
1990 			RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1991 				 ("recv_indicatepkts_in_order: indicate =%d "
1992 				  "seq =%d amsdu =%d\n",
1993 				  preorder_ctrl->indicate_seq,
1994 				  pattrib->seq_num, pattrib->amsdu));
1995 
1996 			plist = plist->next;
1997 			list_del_init(&prframe->list);
1998 
1999 			if (SN_EQUAL(preorder_ctrl->indicate_seq,
2000 				     pattrib->seq_num))	{
2001 				preorder_ctrl->indicate_seq =
2002 					(preorder_ctrl->indicate_seq + 1)&0xFFF;
2003 			}
2004 
2005 			if (!pattrib->amsdu) {
2006 				if ((padapter->bDriverStopped == false) &&
2007 				    (padapter->bSurpriseRemoved == false)) {
2008 					rtw_recv_indicatepkt23a(padapter, prframe);
2009 				}
2010 			} else {
2011 				if (amsdu_to_msdu(padapter, prframe) !=
2012 				    _SUCCESS)
2013 					rtw_free_recvframe23a(prframe);
2014 			}
2015 
2016 			/* Update local variables. */
2017 			bPktInBuf = false;
2018 
2019 		} else {
2020 			bPktInBuf = true;
2021 			break;
2022 		}
2023 
2024 		/* DbgPrint("recv_indicatepkts_in_order():while\n"); */
2025 	}
2026 
2027 	/* spin_unlock_ex(&ppending_recvframe_queue->lock); */
2028 	/* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
2029 
2030 	return bPktInBuf;
2031 }
2032 
2033 int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
2034 			     struct recv_frame *prframe);
recv_indicatepkt_reorder(struct rtw_adapter * padapter,struct recv_frame * prframe)2035 int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
2036 			     struct recv_frame *prframe)
2037 {
2038 	int retval = _SUCCESS;
2039 	struct rx_pkt_attrib *pattrib;
2040 	struct recv_reorder_ctrl *preorder_ctrl;
2041 	struct rtw_queue *ppending_recvframe_queue;
2042 
2043 	pattrib = &prframe->attrib;
2044 	preorder_ctrl = prframe->preorder_ctrl;
2045 	ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2046 
2047 	if (!pattrib->amsdu) {
2048 		/* s1. */
2049 		wlanhdr_to_ethhdr(prframe);
2050 
2051 		if ((pattrib->qos!= 1) || (pattrib->eth_type == ETH_P_ARP) ||
2052 		    (pattrib->ack_policy != 0)) {
2053 			if ((padapter->bDriverStopped == false) &&
2054 			    (padapter->bSurpriseRemoved == false)) {
2055 				RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2056 					 ("@@@@  recv_indicatepkt_reorder -"
2057 					  "recv_func recv_indicatepkt\n"));
2058 
2059 				rtw_recv_indicatepkt23a(padapter, prframe);
2060 				return _SUCCESS;
2061 			}
2062 
2063 			return _FAIL;
2064 		}
2065 
2066 		if (preorder_ctrl->enable == false) {
2067 			/* indicate this recv_frame */
2068 			preorder_ctrl->indicate_seq = pattrib->seq_num;
2069 			rtw_recv_indicatepkt23a(padapter, prframe);
2070 
2071 			preorder_ctrl->indicate_seq =
2072 				(preorder_ctrl->indicate_seq + 1) % 4096;
2073 			return _SUCCESS;
2074 		}
2075 	} else {
2076 		 /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
2077 		if (preorder_ctrl->enable == false) {
2078 			preorder_ctrl->indicate_seq = pattrib->seq_num;
2079 			retval = amsdu_to_msdu(padapter, prframe);
2080 
2081 			preorder_ctrl->indicate_seq =
2082 				(preorder_ctrl->indicate_seq + 1) % 4096;
2083 			return retval;
2084 		}
2085 	}
2086 
2087 	spin_lock_bh(&ppending_recvframe_queue->lock);
2088 
2089 	RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2090 		 ("recv_indicatepkt_reorder: indicate =%d seq =%d\n",
2091 		  preorder_ctrl->indicate_seq, pattrib->seq_num));
2092 
2093 	/* s2. check if winstart_b(indicate_seq) needs to been updated */
2094 	if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
2095 		goto _err_exit;
2096 	}
2097 
2098 	/* s3. Insert all packet into Reorder Queue to maintain its ordering. */
2099 	if (!enqueue_reorder_recvframe23a(preorder_ctrl, prframe)) {
2100 		goto _err_exit;
2101 	}
2102 
2103 	/* s4. */
2104 	/*  Indication process. */
2105 	/*  After Packet dropping and Sliding Window shifting as above,
2106 	    we can now just indicate the packets */
2107 	/*  with the SeqNum smaller than latest WinStart and buffer
2108 	    other packets. */
2109 	/*  */
2110 	/*  For Rx Reorder condition: */
2111 	/*  1. All packets with SeqNum smaller than WinStart => Indicate */
2112 	/*  2. All packets with SeqNum larger than or equal to WinStart =>
2113 	    Buffer it. */
2114 	/*  */
2115 
2116 	if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) {
2117 		mod_timer(&preorder_ctrl->reordering_ctrl_timer,
2118 			  jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
2119 		spin_unlock_bh(&ppending_recvframe_queue->lock);
2120 	} else {
2121 		spin_unlock_bh(&ppending_recvframe_queue->lock);
2122 		del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
2123 	}
2124 	return _SUCCESS;
2125 
2126 _err_exit:
2127 
2128 	spin_unlock_bh(&ppending_recvframe_queue->lock);
2129 	return _FAIL;
2130 }
2131 
rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext)2132 void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext)
2133 {
2134 	struct recv_reorder_ctrl *preorder_ctrl;
2135 	struct rtw_adapter *padapter;
2136 	struct rtw_queue *ppending_recvframe_queue;
2137 
2138 	preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
2139 	padapter = preorder_ctrl->padapter;
2140 	ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2141 
2142 	if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
2143 		return;
2144 	}
2145 
2146 	/* DBG_8723A("+rtw_reordering_ctrl_timeout_handler23a() =>\n"); */
2147 
2148 	spin_lock_bh(&ppending_recvframe_queue->lock);
2149 
2150 	if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true) {
2151 		mod_timer(&preorder_ctrl->reordering_ctrl_timer,
2152 			  jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
2153 	}
2154 
2155 	spin_unlock_bh(&ppending_recvframe_queue->lock);
2156 }
2157 
2158 int process_recv_indicatepkts(struct rtw_adapter *padapter,
2159 			      struct recv_frame *prframe);
process_recv_indicatepkts(struct rtw_adapter * padapter,struct recv_frame * prframe)2160 int process_recv_indicatepkts(struct rtw_adapter *padapter,
2161 			      struct recv_frame *prframe)
2162 {
2163 	int retval = _SUCCESS;
2164 	/* struct recv_priv *precvpriv = &padapter->recvpriv; */
2165 	/* struct rx_pkt_attrib *pattrib = &prframe->attrib; */
2166 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2167 	struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2168 
2169 	if (phtpriv->ht_option == true) { /* B/G/N Mode */
2170 		/* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
2171 
2172 		/*  including perform A-MPDU Rx Ordering Buffer Control */
2173 		if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
2174 			if ((padapter->bDriverStopped == false) &&
2175 			    (padapter->bSurpriseRemoved == false)) {
2176 				retval = _FAIL;
2177 				return retval;
2178 			}
2179 		}
2180 	} else /* B/G mode */
2181 	{
2182 		retval = wlanhdr_to_ethhdr(prframe);
2183 		if (retval != _SUCCESS) {
2184 			RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2185 				 ("wlanhdr_to_ethhdr: drop pkt\n"));
2186 			return retval;
2187 		}
2188 
2189 		if ((padapter->bDriverStopped == false) &&
2190 		    (padapter->bSurpriseRemoved == false)) {
2191 			/* indicate this recv_frame */
2192 			RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2193 				 ("@@@@ process_recv_indicatepkts- "
2194 				  "recv_func recv_indicatepkt\n"));
2195 			rtw_recv_indicatepkt23a(padapter, prframe);
2196 		} else {
2197 			RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2198 				 ("@@@@ process_recv_indicatepkts- "
2199 				  "recv_func free_indicatepkt\n"));
2200 
2201 			RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2202 				 ("recv_func:bDriverStopped(%d) OR "
2203 				  "bSurpriseRemoved(%d)",
2204 				  padapter->bDriverStopped,
2205 				  padapter->bSurpriseRemoved));
2206 			retval = _FAIL;
2207 			return retval;
2208 		}
2209 
2210 	}
2211 
2212 	return retval;
2213 }
2214 
recv_func_prehandle(struct rtw_adapter * padapter,struct recv_frame * rframe)2215 static int recv_func_prehandle(struct rtw_adapter *padapter,
2216 			       struct recv_frame *rframe)
2217 {
2218 	int ret = _SUCCESS;
2219 
2220 	/* check the frame crtl field and decache */
2221 	ret = validate_recv_frame(padapter, rframe);
2222 	if (ret != _SUCCESS) {
2223 		RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
2224 			 ("recv_func: validate_recv_frame fail! drop pkt\n"));
2225 		rtw_free_recvframe23a(rframe);
2226 		goto exit;
2227 	}
2228 
2229 exit:
2230 	return ret;
2231 }
2232 
recv_func_posthandle(struct rtw_adapter * padapter,struct recv_frame * prframe)2233 static int recv_func_posthandle(struct rtw_adapter *padapter,
2234 				struct recv_frame *prframe)
2235 {
2236 	int ret = _SUCCESS;
2237 	struct recv_frame *orig_prframe = prframe;
2238 	struct recv_priv *precvpriv = &padapter->recvpriv;
2239 
2240 	/*  DATA FRAME */
2241 	rtw_led_control(padapter, LED_CTL_RX);
2242 
2243 	prframe = decryptor(padapter, prframe);
2244 	if (prframe == NULL) {
2245 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2246 			 ("decryptor: drop pkt\n"));
2247 		ret = _FAIL;
2248 		goto _recv_data_drop;
2249 	}
2250 
2251 	prframe = recvframe_chk_defrag23a(padapter, prframe);
2252 	if (!prframe) {
2253 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2254 			 ("recvframe_chk_defrag23a: drop pkt\n"));
2255 		goto _recv_data_drop;
2256 	}
2257 
2258 	/*
2259 	 * Pull off crypto headers
2260 	 */
2261 	if (prframe->attrib.iv_len > 0) {
2262 		skb_pull(prframe->pkt, prframe->attrib.iv_len);
2263 	}
2264 
2265 	if (prframe->attrib.icv_len > 0) {
2266 		skb_trim(prframe->pkt,
2267 			 prframe->pkt->len - prframe->attrib.icv_len);
2268 	}
2269 
2270 	prframe = portctrl(padapter, prframe);
2271 	if (!prframe) {
2272 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2273 			 ("portctrl: drop pkt\n"));
2274 		ret = _FAIL;
2275 		goto _recv_data_drop;
2276 	}
2277 
2278 	count_rx_stats(padapter, prframe, NULL);
2279 
2280 	ret = process_recv_indicatepkts(padapter, prframe);
2281 	if (ret != _SUCCESS) {
2282 		RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2283 			 ("recv_func: process_recv_indicatepkts fail!\n"));
2284 		rtw_free_recvframe23a(orig_prframe);/* free this recv_frame */
2285 		goto _recv_data_drop;
2286 	}
2287 	return ret;
2288 
2289 _recv_data_drop:
2290 	precvpriv->rx_drop++;
2291 	return ret;
2292 }
2293 
rtw_recv_entry23a(struct recv_frame * rframe)2294 int rtw_recv_entry23a(struct recv_frame *rframe)
2295 {
2296 	int ret, r;
2297 	struct rtw_adapter *padapter = rframe->adapter;
2298 	struct rx_pkt_attrib *prxattrib = &rframe->attrib;
2299 	struct recv_priv *recvpriv = &padapter->recvpriv;
2300 	struct security_priv *psecuritypriv = &padapter->securitypriv;
2301 	struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2302 
2303 	/* check if need to handle uc_swdec_pending_queue*/
2304 	if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2305 	    psecuritypriv->busetkipkey)	{
2306 		struct recv_frame *pending_frame;
2307 
2308 		while ((pending_frame = rtw_alloc_recvframe23a(&padapter->recvpriv.uc_swdec_pending_queue))) {
2309 			r = recv_func_posthandle(padapter, pending_frame);
2310 			if (r == _SUCCESS)
2311 				DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
2312 		}
2313 	}
2314 
2315 	ret = recv_func_prehandle(padapter, rframe);
2316 
2317 	if (ret == _SUCCESS) {
2318 		/* check if need to enqueue into uc_swdec_pending_queue*/
2319 		if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2320 		    !is_multicast_ether_addr(prxattrib->ra) &&
2321 		    prxattrib->encrypt > 0 &&
2322 		    (prxattrib->bdecrypted == 0) &&
2323 		    !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) &&
2324 		    !psecuritypriv->busetkipkey) {
2325 			rtw_enqueue_recvframe23a(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
2326 			DBG_8723A("%s: no key, enqueue uc_swdec_pending_queue\n", __func__);
2327 			goto exit;
2328 		}
2329 
2330 		ret = recv_func_posthandle(padapter, rframe);
2331 
2332 		recvpriv->rx_pkts++;
2333 	}
2334 
2335 exit:
2336 	return ret;
2337 }
2338 
rtw_signal_stat_timer_hdl23a(unsigned long data)2339 void rtw_signal_stat_timer_hdl23a(unsigned long data)
2340 {
2341 	struct rtw_adapter *adapter = (struct rtw_adapter *)data;
2342 	struct recv_priv *recvpriv = &adapter->recvpriv;
2343 
2344 	u32 tmp_s, tmp_q;
2345 	u8 avg_signal_strength = 0;
2346 	u8 avg_signal_qual = 0;
2347 	u32 num_signal_strength = 0;
2348 	u32 num_signal_qual = 0;
2349 	u8 _alpha = 3;	/* this value is based on converging_constant = 5000 */
2350 			/* and sampling_interval = 1000 */
2351 
2352 	if (adapter->recvpriv.is_signal_dbg) {
2353 		/* update the user specific value, signal_strength_dbg, */
2354 		/* to signal_strength, rssi */
2355 		adapter->recvpriv.signal_strength =
2356 			adapter->recvpriv.signal_strength_dbg;
2357 		adapter->recvpriv.rssi =
2358 			(s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
2359 	} else {
2360 		if (recvpriv->signal_strength_data.update_req == 0) {
2361 			/*  update_req is clear, means we got rx */
2362 			avg_signal_strength =
2363 				recvpriv->signal_strength_data.avg_val;
2364 			num_signal_strength =
2365 				recvpriv->signal_strength_data.total_num;
2366 			/*  after avg_vals are acquired, we can re-stat */
2367 			/* the signal values */
2368 			recvpriv->signal_strength_data.update_req = 1;
2369 		}
2370 
2371 		if (recvpriv->signal_qual_data.update_req == 0) {
2372 			/*  update_req is clear, means we got rx */
2373 			avg_signal_qual = recvpriv->signal_qual_data.avg_val;
2374 			num_signal_qual = recvpriv->signal_qual_data.total_num;
2375 			/*  after avg_vals are acquired, we can re-stat */
2376 			/*the signal values */
2377 			recvpriv->signal_qual_data.update_req = 1;
2378 		}
2379 
2380 		/* update value of signal_strength, rssi, signal_qual */
2381 		if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
2382 			tmp_s = (avg_signal_strength + (_alpha - 1) *
2383 				 recvpriv->signal_strength);
2384 			if (tmp_s %_alpha)
2385 				tmp_s = tmp_s / _alpha + 1;
2386 			else
2387 				tmp_s = tmp_s / _alpha;
2388 			if (tmp_s > 100)
2389 				tmp_s = 100;
2390 
2391 			tmp_q = (avg_signal_qual + (_alpha - 1) *
2392 				 recvpriv->signal_qual);
2393 			if (tmp_q %_alpha)
2394 				tmp_q = tmp_q / _alpha + 1;
2395 			else
2396 				tmp_q = tmp_q / _alpha;
2397 			if (tmp_q > 100)
2398 				tmp_q = 100;
2399 
2400 			recvpriv->signal_strength = tmp_s;
2401 			recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
2402 			recvpriv->signal_qual = tmp_q;
2403 
2404 			DBG_8723A("%s signal_strength:%3u, rssi:%3d, "
2405 				  "signal_qual:%3u, num_signal_strength:%u, "
2406 				  "num_signal_qual:%u\n",
2407 				  __func__, recvpriv->signal_strength,
2408 				  recvpriv->rssi, recvpriv->signal_qual,
2409 				  num_signal_strength, num_signal_qual
2410 			);
2411 		}
2412 	}
2413 	rtw_set_signal_stat_timer(recvpriv);
2414 }
2415