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