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