1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
14 ******************************************************************************/
16 #include <osdep_service.h>
17 #include <drv_types.h>
18 #include <recv_osdep.h>
19 #include <mlme_osdep.h>
21 #include <linux/if_ether.h>
23 #include <linux/ieee80211.h>
25 #include <rtl8723a_recv.h>
26 #include <rtl8723a_xmit.h>
28 void rtw_signal_stat_timer_hdl23a(unsigned long data);
30 void _rtw_init_sta_recv_priv23a(struct sta_recv_priv *psta_recvpriv)
35 spin_lock_init(&psta_recvpriv->lock);
37 /* for (i = 0; i<MAX_RX_NUMBLKS; i++) */
38 /* _rtw_init_queue23a(&psta_recvpriv->blk_strms[i]); */
40 _rtw_init_queue23a(&psta_recvpriv->defrag_q);
45 int _rtw_init_recv_priv23a(struct recv_priv *precvpriv,
46 struct rtw_adapter *padapter)
48 struct recv_frame *precvframe;
52 spin_lock_init(&precvpriv->lock);
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);
58 precvpriv->adapter = padapter;
60 for (i = 0; i < NR_RECVFRAME ; i++) {
61 precvframe = kzalloc(sizeof(struct recv_frame), GFP_KERNEL);
64 INIT_LIST_HEAD(&precvframe->list);
66 list_add_tail(&precvframe->list,
67 &precvpriv->free_recv_queue.queue);
69 precvframe->adapter = padapter;
73 precvpriv->free_recvframe_cnt = i;
74 precvpriv->rx_pending_cnt = 1;
76 res = rtl8723au_init_recv_priv(padapter);
78 setup_timer(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl23a,
79 (unsigned long)padapter);
81 precvpriv->signal_stat_sampling_interval = 1000; /* ms */
83 rtw_set_signal_stat_timer(precvpriv);
88 void _rtw_free_recv_priv23a (struct recv_priv *precvpriv)
90 struct rtw_adapter *padapter = precvpriv->adapter;
91 struct recv_frame *precvframe;
92 struct list_head *plist, *ptmp;
94 rtw_free_uc_swdec_pending_queue23a(padapter);
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);
102 rtl8723au_free_recv_priv(padapter);
105 struct recv_frame *rtw_alloc_recvframe23a(struct rtw_queue *pfree_recv_queue)
107 struct recv_frame *pframe;
108 struct list_head *plist, *phead;
109 struct rtw_adapter *padapter;
110 struct recv_priv *precvpriv;
112 spin_lock_bh(&pfree_recv_queue->lock);
114 if (list_empty(&pfree_recv_queue->queue))
117 phead = get_list_head(pfree_recv_queue);
121 pframe = container_of(plist, struct recv_frame, list);
123 list_del_init(&pframe->list);
124 padapter = pframe->adapter;
126 precvpriv = &padapter->recvpriv;
127 if (pfree_recv_queue == &precvpriv->free_recv_queue)
128 precvpriv->free_recvframe_cnt--;
132 spin_unlock_bh(&pfree_recv_queue->lock);
137 int rtw_free_recvframe23a(struct recv_frame *precvframe)
139 struct rtw_adapter *padapter = precvframe->adapter;
140 struct recv_priv *precvpriv = &padapter->recvpriv;
141 struct rtw_queue *pfree_recv_queue;
143 if (precvframe->pkt) {
144 dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */
145 precvframe->pkt = NULL;
148 pfree_recv_queue = &precvpriv->free_recv_queue;
149 spin_lock_bh(&pfree_recv_queue->lock);
151 list_del_init(&precvframe->list);
153 list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
156 if (pfree_recv_queue == &precvpriv->free_recv_queue)
157 precvpriv->free_recvframe_cnt++;
160 spin_unlock_bh(&pfree_recv_queue->lock);
167 int rtw_enqueue_recvframe23a(struct recv_frame *precvframe, struct rtw_queue *queue)
169 struct rtw_adapter *padapter = precvframe->adapter;
170 struct recv_priv *precvpriv = &padapter->recvpriv;
172 spin_lock_bh(&queue->lock);
174 list_del_init(&precvframe->list);
176 list_add_tail(&precvframe->list, get_list_head(queue));
179 if (queue == &precvpriv->free_recv_queue)
180 precvpriv->free_recvframe_cnt++;
183 spin_unlock_bh(&queue->lock);
189 caller : defrag ; recvframe_chk_defrag23a in recv_thread (passive)
190 pframequeue: defrag_queue : will be accessed in recv_thread (passive)
192 using spinlock to protect
196 static void rtw_free_recvframe23a_queue(struct rtw_queue *pframequeue)
198 struct recv_frame *hdr;
199 struct list_head *plist, *phead, *ptmp;
201 spin_lock(&pframequeue->lock);
203 phead = get_list_head(pframequeue);
206 list_for_each_safe(plist, ptmp, phead) {
207 hdr = container_of(plist, struct recv_frame, list);
208 rtw_free_recvframe23a(hdr);
211 spin_unlock(&pframequeue->lock);
214 u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter)
217 struct recv_frame *pending_frame;
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__);
228 int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue *queue)
230 spin_lock_bh(&queue->lock);
232 list_del_init(&precvbuf->list);
233 list_add(&precvbuf->list, get_list_head(queue));
235 spin_unlock_bh(&queue->lock);
240 int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue)
244 spin_lock_irqsave(&queue->lock, irqL);
246 list_del_init(&precvbuf->list);
248 list_add_tail(&precvbuf->list, get_list_head(queue));
249 spin_unlock_irqrestore(&queue->lock, irqL);
253 struct recv_buf *rtw_dequeue_recvbuf23a (struct rtw_queue *queue)
256 struct recv_buf *precvbuf;
257 struct list_head *plist, *phead;
259 spin_lock_irqsave(&queue->lock, irqL);
261 if (list_empty(&queue->queue)) {
264 phead = get_list_head(queue);
268 precvbuf = container_of(plist, struct recv_buf, list);
270 list_del_init(&precvbuf->list);
273 spin_unlock_irqrestore(&queue->lock, irqL);
278 int recvframe_chkmic(struct rtw_adapter *adapter,
279 struct recv_frame *precvframe);
280 int recvframe_chkmic(struct rtw_adapter *adapter,
281 struct recv_frame *precvframe) {
283 int i, res = _SUCCESS;
286 u8 bmic_err = false, brpt_micerror = true;
287 u8 *pframe, *payload, *pframemic;
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;
294 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
295 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
298 stainfo = rtw_get_stainfo23a(&adapter->stapriv, &prxattrib->ta[0]);
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);
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];
311 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
312 "recvframe_chkmic: bcmc key\n");
314 if (!psecuritypriv->binstallGrpkey) {
316 RT_TRACE(_module_rtl871x_recv_c_,
318 "recvframe_chkmic:didn't install group key!\n");
319 DBG_8723A("\n recvframe_chkmic:didn't "
320 "install group key!!!!!!\n");
324 mickey = &stainfo->dot11tkiprxmickey.skey[0];
325 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
326 "recvframe_chkmic: unicast key\n");
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 +
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);
340 /* care the length of the data */
341 rtw_seccalctkipmic23a(mickey, pframe, payload,
342 datalen, &miccode[0],
343 (unsigned char)prxattrib->priority);
345 pframemic = payload + datalen;
349 for (i = 0; i < 8; i++) {
350 if (miccode[i] != *(pframemic + i)) {
351 RT_TRACE(_module_rtl871x_recv_c_,
353 "recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x)\n",
355 i, *(pframemic + i));
360 if (bmic_err == true) {
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));
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_,
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));
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);
398 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
399 "ra = %pM psecuritypriv->binstallGrpkey =%d\n",
401 psecuritypriv->binstallGrpkey);
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;
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->"
420 prxattrib->bdecrypted);
422 RT_TRACE(_module_rtl871x_recv_c_,
424 "mic error :prxattrib->bdecrypted =%d\n",
425 prxattrib->bdecrypted);
426 DBG_8723A(" mic error :prxattrib->"
428 prxattrib->bdecrypted);
434 if (!psecuritypriv->bcheck_grpkey &&
435 is_multicast_ether_addr(prxattrib->ra)) {
436 psecuritypriv->bcheck_grpkey = 1;
437 RT_TRACE(_module_rtl871x_recv_c_,
439 "psecuritypriv->bcheck_grpkey = true\n");
443 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
444 "recvframe_chkmic: rtw_get_stainfo23a ==NULL!!!\n");
447 skb_trim(precvframe->pkt, precvframe->pkt->len - 8);
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);
460 struct recv_frame *decryptor(struct rtw_adapter *padapter,
461 struct recv_frame *precv_frame)
463 struct rx_pkt_attrib *prxattrib = &precv_frame->attrib;
464 struct security_priv *psecuritypriv = &padapter->securitypriv;
465 struct recv_frame *return_packet = precv_frame;
468 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
469 "prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n",
470 prxattrib->bdecrypted, prxattrib->encrypt);
472 if (prxattrib->encrypt > 0) {
473 u8 *iv = precv_frame->pkt->data + prxattrib->hdrlen;
475 prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
477 if (prxattrib->key_index > WEP_KEYS) {
478 DBG_8723A("prxattrib->key_index(%d) > WEP_KEYS\n",
479 prxattrib->key_index);
481 switch (prxattrib->encrypt) {
482 case WLAN_CIPHER_SUITE_WEP40:
483 case WLAN_CIPHER_SUITE_WEP104:
484 prxattrib->key_index =
485 psecuritypriv->dot11PrivacyKeyIndex;
487 case WLAN_CIPHER_SUITE_TKIP:
488 case WLAN_CIPHER_SUITE_CCMP:
490 prxattrib->key_index =
491 psecuritypriv->dot118021XGrpKeyid;
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);
504 case WLAN_CIPHER_SUITE_TKIP:
505 res = rtw_tkip_decrypt23a(padapter, precv_frame);
507 case WLAN_CIPHER_SUITE_CCMP:
508 res = rtw_aes_decrypt23a(padapter, precv_frame);
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;
520 rtw_free_recvframe23a(return_packet);
521 return_packet = NULL;
526 return return_packet;
529 /* set the security information in the recv_frame */
530 static struct recv_frame *portctrl(struct rtw_adapter *adapter,
531 struct recv_frame *precv_frame)
535 struct recv_frame *pfhdr;
536 struct sta_info *psta;
537 struct sta_priv *pstapriv ;
538 struct recv_frame *prtnframe;
540 u16 eapol_type = ETH_P_PAE;/* for Funia BD's WPA issue */
541 struct rx_pkt_attrib *pattrib;
543 pstapriv = &adapter->stapriv;
545 auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
548 pattrib = &pfhdr->attrib;
549 psta_addr = pattrib->ta;
550 psta = rtw_get_stainfo23a(pstapriv, psta_addr);
552 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
553 "########portctrl:adapter->securitypriv.dot11AuthAlgrthm =%d\n",
554 adapter->securitypriv.dot11AuthAlgrthm);
556 prtnframe = precv_frame;
558 if (auth_alg == dot11AuthAlgrthm_8021X) {
560 ptr = pfhdr->pkt->data + pfhdr->attrib.hdrlen;
562 ether_type = (ptr[6] << 8) | ptr[7];
564 if (psta && psta->ieee8021x_blocked) {
566 /* only accept EAPOL frame */
567 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
568 "########portctrl:psta->ieee8021x_blocked ==1\n");
570 if (ether_type != eapol_type) {
571 /* free this frame */
572 rtw_free_recvframe23a(precv_frame);
581 int recv_decache(struct recv_frame *precv_frame, u8 bretry,
582 struct stainfo_rxcache *prxcache);
583 int recv_decache(struct recv_frame *precv_frame, u8 bretry,
584 struct stainfo_rxcache *prxcache)
586 int tid = precv_frame->attrib.priority;
588 u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) |
589 (precv_frame->attrib.frag_num & 0xf);
594 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
595 "recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n",
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]);
611 prxcache->tid_rxseq[tid] = seq_ctrl;
618 void process23a_pwrbit_data(struct rtw_adapter *padapter,
619 struct recv_frame *precv_frame);
620 void process23a_pwrbit_data(struct rtw_adapter *padapter,
621 struct recv_frame *precv_frame)
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;
631 psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
634 pwrbit = ieee80211_has_pm(hdr->frame_control);
637 if (!(psta->state & WIFI_SLEEP_STATE))
638 stop_sta_xmit23a(padapter, psta);
640 if (psta->state & WIFI_SLEEP_STATE)
641 wakeup_sta_to_xmit23a(padapter, psta);
648 void process_wmmps_data(struct rtw_adapter *padapter,
649 struct recv_frame *precv_frame);
650 void process_wmmps_data(struct rtw_adapter *padapter,
651 struct recv_frame *precv_frame)
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;
658 psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
664 if (!psta->qos_option)
667 if (!(psta->qos_info & 0xf))
670 if (psta->state & WIFI_SLEEP_STATE) {
673 switch (pattrib->priority) {
676 wmmps_ac = psta->uapsd_bk & BIT(1);
680 wmmps_ac = psta->uapsd_vi & BIT(1);
684 wmmps_ac = psta->uapsd_vo & BIT(1);
689 wmmps_ac = psta->uapsd_be & BIT(1);
694 if (psta->sleepq_ac_len > 0) {
695 /* process received triggered frame */
696 xmit_delivery_enabled_frames23a(padapter, psta);
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,
709 static void count_rx_stats(struct rtw_adapter *padapter,
710 struct recv_frame *prframe, struct sta_info *sta)
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;
718 sz = prframe->pkt->len;
719 precvpriv->rx_bytes += sz;
721 padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
723 if ((!is_broadcast_ether_addr(pattrib->dst)) &&
724 (!is_multicast_ether_addr(pattrib->dst)))
725 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
730 psta = prframe->psta;
733 pstats = &psta->sta_stats;
735 pstats->rx_data_pkts++;
736 pstats->rx_bytes += sz;
740 static int sta2sta_data_frame(struct rtw_adapter *adapter,
741 struct recv_frame *precv_frame,
742 struct sta_info**psta)
744 struct sk_buff *skb = precv_frame->pkt;
745 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
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);
753 int bmcast = is_multicast_ether_addr(pattrib->dst);
757 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
758 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
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_,
768 if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
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)) {
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");
791 sta_addr = pattrib->bssid;
793 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
795 /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */
796 if (!is_multicast_ether_addr(pattrib->bssid)) {
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)) {
808 sta_addr = pattrib->src;
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);
823 *psta = rtw_get_bcmc_stainfo23a(adapter);
825 *psta = rtw_get_stainfo23a(pstapriv, sta_addr); /* get ap_info */
828 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
829 "can't get psta under sta2sta_data_frame ; drop pkt\n");
839 int ap2sta_data_frame(struct rtw_adapter *adapter,
840 struct recv_frame *precv_frame,
841 struct sta_info **psta);
842 int ap2sta_data_frame(struct rtw_adapter *adapter,
843 struct recv_frame *precv_frame,
844 struct sta_info **psta)
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;
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);
858 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
859 (check_fwstate(pmlmepriv, _FW_LINKED) ||
860 check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) {
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_,
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",
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",
886 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
887 "mybssid=%pM\n", mybssid);
890 DBG_8723A("issue_deauth23a to the nonassociated ap=%pM for the reason(7)\n",
892 issue_deauth23a(adapter, pattrib->bssid,
893 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
901 *psta = rtw_get_bcmc_stainfo23a(adapter);
904 *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
907 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
908 "ap2sta: can't get psta under STATION_MODE; drop pkt\n");
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;
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);
930 ether_addr_copy(pattrib->bssid, mybssid);
933 *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
935 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
936 "can't get psta under MP_MODE ; drop pkt\n");
940 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
942 ret = RTW_RX_HANDLED;
945 if (ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
946 *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
948 DBG_8723A("issue_deauth23a to the ap=%pM for the reason(7)\n",
951 issue_deauth23a(adapter, pattrib->bssid,
952 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
966 int sta2ap_data_frame(struct rtw_adapter *adapter,
967 struct recv_frame *precv_frame,
968 struct sta_info **psta);
969 int sta2ap_data_frame(struct rtw_adapter *adapter,
970 struct recv_frame *precv_frame,
971 struct sta_info **psta)
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);
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)) {
990 *psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
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",
997 issue_deauth23a(adapter, pattrib->src,
998 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1000 ret = RTW_RX_HANDLED;
1004 process23a_pwrbit_data(adapter, precv_frame);
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);
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;
1019 u8 *myhwaddr = myid(&adapter->eeprompriv);
1021 if (!ether_addr_equal(pattrib->ra, myhwaddr)) {
1022 ret = RTW_RX_HANDLED;
1025 DBG_8723A("issue_deauth23a to sta=%pM for the reason(7)\n",
1027 issue_deauth23a(adapter, pattrib->src,
1028 WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1029 ret = RTW_RX_HANDLED;
1040 static int validate_recv_ctrl_frame(struct rtw_adapter *padapter,
1041 struct recv_frame *precv_frame)
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;
1049 if (!ieee80211_is_ctl(hdr->frame_control))
1052 /* receive the frames that ra(a1) is my address */
1053 if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv)))
1056 /* only handle ps-poll */
1057 if (ieee80211_is_pspoll(hdr->frame_control)) {
1058 struct ieee80211_pspoll *psp = (struct ieee80211_pspoll *)hdr;
1061 struct sta_info *psta = NULL;
1063 aid = le16_to_cpu(psp->aid) & 0x3fff;
1064 psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
1066 if (!psta || psta->aid != aid)
1069 /* for rx pkt statistics */
1070 psta->sta_stats.rx_ctrl_pkts++;
1072 switch (pattrib->priority) {
1075 wmmps_ac = psta->uapsd_bk & BIT(0);
1079 wmmps_ac = psta->uapsd_vi & BIT(0);
1083 wmmps_ac = psta->uapsd_vo & BIT(0);
1088 wmmps_ac = psta->uapsd_be & BIT(0);
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;
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;
1107 spin_lock_bh(&pxmitpriv->lock);
1109 xmitframe_phead = get_list_head(&psta->sleep_q);
1110 xmitframe_plist = xmitframe_phead->next;
1112 if (!list_empty(xmitframe_phead)) {
1113 pxmitframe = container_of(xmitframe_plist,
1117 xmitframe_plist = xmitframe_plist->next;
1119 list_del_init(&pxmitframe->list);
1123 if (psta->sleepq_len>0)
1124 pxmitframe->attrib.mdata = 1;
1126 pxmitframe->attrib.mdata = 0;
1128 pxmitframe->attrib.triggered = 1;
1130 /* DBG_8723A("handling ps-poll, q_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1132 rtl8723au_hal_xmitframe_enqueue(padapter,
1135 if (psta->sleepq_len == 0) {
1136 pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
1138 /* DBG_8723A("after handling ps-poll, tim =%x\n", pstapriv->tim_bitmap); */
1140 /* update BCN for TIM IE */
1141 /* update_BCNTIM(padapter); */
1142 update_beacon23a(padapter, WLAN_EID_TIM,
1146 /* spin_unlock_bh(&psta->sleep_q.lock); */
1147 spin_unlock_bh(&pxmitpriv->lock);
1150 /* spin_unlock_bh(&psta->sleep_q.lock); */
1151 spin_unlock_bh(&pxmitpriv->lock);
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 "
1159 /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1160 issue_nulldata23a(padapter,
1164 DBG_8723A("error!psta->sleepq"
1167 psta->sleepq_len = 0;
1170 pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
1172 /* update BCN for TIM IE */
1173 /* update_BCNTIM(padapter); */
1174 update_beacon23a(padapter, WLAN_EID_TIM,
1185 struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1186 struct recv_frame *precv_frame);
1187 static int validate_recv_mgnt_frame(struct rtw_adapter *padapter,
1188 struct recv_frame *precv_frame)
1190 struct sta_info *psta;
1191 struct sk_buff *skb;
1192 struct ieee80211_hdr *hdr;
1193 /* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */
1195 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1196 "+validate_recv_mgnt_frame\n");
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__);
1205 skb = precv_frame->pkt;
1206 hdr = (struct ieee80211_hdr *) skb->data;
1208 /* for rx pkt statistics */
1209 psta = rtw_get_stainfo23a(&padapter->stapriv, hdr->addr2);
1211 psta->sta_stats.rx_mgnt_pkts++;
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,
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++;
1225 psta->sta_stats.rx_probersp_uo_pkts++;
1229 mgt_dispatcher23a(padapter, precv_frame);
1234 static int validate_recv_data_frame(struct rtw_adapter *adapter,
1235 struct recv_frame *precv_frame)
1239 struct sta_info *psta = NULL;
1240 struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
1241 struct security_priv *psecuritypriv = &adapter->securitypriv;
1243 struct sk_buff *skb = precv_frame->pkt;
1244 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1248 bretry = ieee80211_has_retry(hdr->frame_control);
1249 pda = ieee80211_get_DA(hdr);
1250 psa = ieee80211_get_SA(hdr);
1252 ether_addr_copy(pattrib->dst, pda);
1253 ether_addr_copy(pattrib->src, psa);
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);
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);
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);
1278 case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
1280 * There is no BSSID in this case, but the driver has been
1281 * using addr1 so far, so keep it for now.
1283 ether_addr_copy(pattrib->bssid, hdr->addr1);
1284 ether_addr_copy(pattrib->ra, hdr->addr1);
1285 ether_addr_copy(pattrib->ta, hdr->addr2);
1287 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, "case 3\n");
1291 if ((ret == _FAIL) || (ret == RTW_RX_HANDLED))
1295 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1296 "after to_fr_ds_chk; psta == NULL\n");
1301 /* psta->rssi = prxcmd->rssi; */
1302 /* psta->signal_quality = prxcmd->sq; */
1303 precv_frame->psta = psta;
1305 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
1306 if (ieee80211_has_a4(hdr->frame_control))
1307 pattrib->hdrlen += ETH_ALEN;
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);
1314 pattrib->priority = qos_ctrl & IEEE80211_QOS_CTL_TID_MASK;
1315 pattrib->ack_policy = (qos_ctrl >> 5) & 3;
1317 (qos_ctrl & IEEE80211_QOS_CTL_A_MSDU_PRESENT) >> 7;
1318 pattrib->hdrlen += IEEE80211_QOS_CTL_LEN;
1320 if (pattrib->priority != 0 && pattrib->priority != 3) {
1321 adapter->recvpriv.bIsAnyNonBEPkts = true;
1324 pattrib->priority = 0;
1325 pattrib->ack_policy = 0;
1329 if (pattrib->order) { /* HT-CTRL 11n */
1330 pattrib->hdrlen += 4;
1333 precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1335 /* decache, drop duplicate recv packets */
1336 if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
1338 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1339 "decache : drop pkt\n");
1344 if (pattrib->privacy) {
1345 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1346 "validate_recv_data_frame:pattrib->privacy =%x\n",
1348 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1349 "^^^^^^^^^^^is_multicast_ether_addr(pattrib->ra(0x%02x)) =%d^^^^^^^^^^^^^^^6\n",
1351 is_multicast_ether_addr(pattrib->ra));
1353 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
1354 is_multicast_ether_addr(pattrib->ra));
1356 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1357 "pattrib->encrypt =%d\n", pattrib->encrypt);
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;
1365 case WLAN_CIPHER_SUITE_TKIP:
1366 pattrib->iv_len = IEEE80211_TKIP_IV_LEN;
1367 pattrib->icv_len = IEEE80211_TKIP_ICV_LEN;
1369 case WLAN_CIPHER_SUITE_CCMP:
1370 pattrib->iv_len = IEEE80211_CCMP_HDR_LEN;
1371 pattrib->icv_len = IEEE80211_CCMP_MIC_LEN;
1374 pattrib->iv_len = 0;
1375 pattrib->icv_len = 0;
1379 pattrib->encrypt = 0;
1380 pattrib->iv_len = 0;
1381 pattrib->icv_len = 0;
1391 static void dump_rx_pkt(struct sk_buff *skb, u16 type, int level)
1397 ((level == 2) && (type == IEEE80211_FTYPE_MGMT)) ||
1398 ((level == 3) && (type == IEEE80211_FTYPE_DATA))) {
1402 DBG_8723A("#############################\n");
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),
1410 DBG_8723A("#############################\n");
1414 static int validate_recv_frame(struct rtw_adapter *adapter,
1415 struct recv_frame *precv_frame)
1417 /* shall check frame subtype, to / from ds, da, bssid */
1419 /* then call check if rx seq/frag. duplicated. */
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;
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;
1435 /* add version chk */
1437 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1438 "validate_recv_data_frame fail! (ver!= 0)\n");
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;
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);
1453 GetHalDefVar8192CUsb(adapter, HAL_DEF_DBG_DUMP_RXPKT, &bDumpRxPkt);
1455 if (unlikely(bDumpRxPkt == 1))
1456 dump_rx_pkt(skb, type, bDumpRxPkt);
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");
1465 retval = _FAIL; /* only data frame return _SUCCESS */
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");
1473 retval = _FAIL; /* only data frame return _SUCCESS */
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;
1481 precvpriv->rx_drop++;
1485 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1486 "validate_recv_data_frame fail! type = 0x%x\n", type);
1495 /* remove the wlanhdr and add the eth_hdr */
1497 static int wlanhdr_to_ethhdr (struct recv_frame *precvframe)
1499 u16 eth_type, len, hdrlen;
1502 struct rtw_adapter *adapter = precvframe->adapter;
1503 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1505 struct sk_buff *skb = precvframe->pkt;
1507 struct rx_pkt_attrib *pattrib = &precvframe->attrib;
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 */
1523 hdrlen += SNAP_SIZE;
1525 /* Leave Ethernet header part of hdr and full payload */
1527 eth_type = (psnap[0] << 8) | psnap[1];
1530 len = skb->len - hdrlen;
1532 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1533 "=== pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n",
1534 pattrib->hdrlen, pattrib->iv_len);
1536 pattrib->eth_type = eth_type;
1537 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
1543 /* append rx status for mp test packets */
1545 ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) + 2) - 24);
1546 memcpy(ptr, skb->head, 24);
1549 ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) +
1553 ether_addr_copy(ptr, pattrib->dst);
1554 ether_addr_copy(ptr + ETH_ALEN, pattrib->src);
1557 put_unaligned_be16(len, ptr + 12);
1564 /* perform defrag */
1565 struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1566 struct rtw_queue *defrag_q);
1567 struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1568 struct rtw_queue *defrag_q)
1570 struct list_head *plist, *phead, *ptmp;
1571 u8 *data, wlanhdr_offset;
1573 struct recv_frame *pnfhdr;
1574 struct recv_frame *prframe, *pnextrframe;
1575 struct rtw_queue *pfree_recv_queue;
1576 struct sk_buff *skb;
1581 pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
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);
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);
1600 phead = get_list_head(defrag_q);
1602 data = prframe->pkt->data;
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) */
1609 if (curfragnum != pnfhdr->attrib.frag_num) {
1610 /* the fragment number must be increasing
1612 /* release the defrag_q & prframe */
1613 rtw_free_recvframe23a(prframe);
1614 rtw_free_recvframe23a_queue(defrag_q);
1620 /* copy the 2nd~n fragment frame's payload to the
1622 /* get the 2nd~last fragment frame's payload */
1624 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1626 skb_pull(pnfhdr->pkt, wlanhdr_offset);
1628 /* append to first fragment frame's tail
1629 (if privacy frame, pull the ICV) */
1631 skb_trim(skb, skb->len - prframe->attrib.icv_len);
1633 memcpy(skb_tail_pointer(skb), pnfhdr->pkt->data,
1636 skb_put(skb, pnfhdr->pkt->len);
1638 prframe->attrib.icv_len = pnfhdr->attrib.icv_len;
1641 /* free the defrag_q queue and return the prframe */
1642 rtw_free_recvframe23a_queue(defrag_q);
1644 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1645 "Performance defrag!!!!!\n");
1652 /* check if need to defrag, if needed queue the frame to defrag_q */
1653 struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1654 struct recv_frame *precv_frame)
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;
1668 pstapriv = &padapter->stapriv;
1670 pfhdr = precv_frame;
1672 pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1674 /* need to define struct of wlan header frame ctrl */
1675 ismfrag = pfhdr->attrib.mfrag;
1676 fragnum = pfhdr->attrib.frag_num;
1678 psta_addr = pfhdr->attrib.ta;
1679 psta = rtw_get_stainfo23a(pstapriv, psta_addr);
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;
1689 pdefrag_q = &psta->sta_recvpriv.defrag_q;
1691 if ((ismfrag == 0) && (fragnum == 0)) {
1692 prtnframe = precv_frame;/* isn't a fragment frame */
1696 /* 0~(n-1) fragment frame */
1697 /* enqueue to defraf_g */
1698 if (pdefrag_q != NULL) {
1700 /* the first fragment */
1701 if (!list_empty(&pdefrag_q->queue)) {
1702 /* free current defrag_q */
1703 rtw_free_recvframe23a_queue(pdefrag_q);
1707 /* Then enqueue the 0~(n-1) fragment into the
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); */
1715 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1716 "Enqueuq: ismfrag = %d, fragnum = %d\n",
1722 /* can't find this ta's defrag_queue,
1723 so free this recv_frame */
1724 rtw_free_recvframe23a(precv_frame);
1726 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1727 "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
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); */
1741 /* call recvframe_defrag to defrag */
1742 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1743 "defrag: ismfrag = %d, fragnum = %d\n",
1745 precv_frame = recvframe_defrag(padapter, pdefrag_q);
1746 prtnframe = precv_frame;
1748 /* can't find this ta's defrag_queue,
1749 so free this recv_frame */
1750 rtw_free_recvframe23a(precv_frame);
1752 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1753 "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
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);
1774 int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe);
1775 int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe)
1777 struct rx_pkt_attrib *pattrib;
1778 struct sk_buff *skb, *sub_skb;
1779 struct sk_buff_head skb_list;
1781 pattrib = &prframe->attrib;
1784 skb_pull(skb, prframe->attrib.hdrlen);
1785 __skb_queue_head_init(&skb_list);
1787 ieee80211_amsdu_to_8023s(skb, &skb_list, NULL, 0, 0, false);
1789 while (!skb_queue_empty(&skb_list)) {
1790 sub_skb = __skb_dequeue(&skb_list);
1792 sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
1793 sub_skb->dev = padapter->pnetdev;
1795 sub_skb->ip_summed = CHECKSUM_NONE;
1800 prframe->pkt = NULL;
1801 rtw_free_recvframe23a(prframe);
1805 int 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)
1808 u8 wsize = preorder_ctrl->wsize_b;
1809 u16 wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;
1811 /* Rx Reorder initialize condition. */
1812 if (preorder_ctrl->indicate_seq == 0xFFFF)
1813 preorder_ctrl->indicate_seq = seq_num;
1815 /* Drop out the packet which SeqNum is smaller than WinStart */
1816 if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
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 */
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;
1832 preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
1837 static int enqueue_reorder_recvframe23a(struct recv_reorder_ctrl *preorder_ctrl,
1838 struct recv_frame *prframe)
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;
1846 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1847 /* DbgPrint("+enqueue_reorder_recvframe23a()\n"); */
1849 /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1850 /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1852 phead = get_list_head(ppending_recvframe_queue);
1854 list_for_each_safe(plist, ptmp, phead) {
1855 hdr = container_of(plist, struct recv_frame, list);
1856 pnextattrib = &hdr->attrib;
1858 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) {
1860 } else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
1861 /* Duplicate entry is found!! Do not insert current entry. */
1863 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1869 /* DbgPrint("enqueue_reorder_recvframe23a():while\n"); */
1872 /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1873 /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1875 list_del_init(&prframe->list);
1877 list_add_tail(&prframe->list, plist);
1879 /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1880 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1885 int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1886 struct recv_reorder_ctrl *preorder_ctrl,
1888 int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1889 struct recv_reorder_ctrl *preorder_ctrl,
1892 /* u8 bcancelled; */
1893 struct list_head *phead, *plist;
1894 struct recv_frame *prframe;
1895 struct rx_pkt_attrib *pattrib;
1897 int bPktInBuf = false;
1898 struct recv_priv *precvpriv;
1899 struct rtw_queue *ppending_recvframe_queue;
1901 precvpriv = &padapter->recvpriv;
1902 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1903 /* DbgPrint("+recv_indicatepkts_in_order\n"); */
1905 /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1906 /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1908 phead = get_list_head(ppending_recvframe_queue);
1909 plist = phead->next;
1911 /* Handling some condition for forced indicate case. */
1913 if (list_empty(phead)) {
1914 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1915 /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1919 prframe = container_of(plist, struct recv_frame, list);
1920 pattrib = &prframe->attrib;
1921 preorder_ctrl->indicate_seq = pattrib->seq_num;
1924 /* Prepare indication list and indication. */
1925 /* Check if there is any packet need indicate. */
1926 while (!list_empty(phead)) {
1928 prframe = container_of(plist, struct recv_frame, list);
1929 pattrib = &prframe->attrib;
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);
1937 plist = plist->next;
1938 list_del_init(&prframe->list);
1940 if (SN_EQUAL(preorder_ctrl->indicate_seq,
1941 pattrib->seq_num)) {
1942 preorder_ctrl->indicate_seq =
1943 (preorder_ctrl->indicate_seq + 1)&0xFFF;
1946 if (!pattrib->amsdu) {
1947 if ((padapter->bDriverStopped == false) &&
1948 (padapter->bSurpriseRemoved == false)) {
1949 rtw_recv_indicatepkt23a(padapter, prframe);
1952 if (amsdu_to_msdu(padapter, prframe) !=
1954 rtw_free_recvframe23a(prframe);
1957 /* Update local variables. */
1965 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
1968 /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1969 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1974 int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
1975 struct recv_frame *prframe);
1976 int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
1977 struct recv_frame *prframe)
1979 int retval = _SUCCESS;
1980 struct rx_pkt_attrib *pattrib;
1981 struct recv_reorder_ctrl *preorder_ctrl;
1982 struct rtw_queue *ppending_recvframe_queue;
1984 pattrib = &prframe->attrib;
1985 preorder_ctrl = prframe->preorder_ctrl;
1986 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1988 if (!pattrib->amsdu) {
1990 wlanhdr_to_ethhdr(prframe);
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");
1999 rtw_recv_indicatepkt23a(padapter, prframe);
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);
2011 preorder_ctrl->indicate_seq =
2012 (preorder_ctrl->indicate_seq + 1) % 4096;
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);
2021 preorder_ctrl->indicate_seq =
2022 (preorder_ctrl->indicate_seq + 1) % 4096;
2027 spin_lock_bh(&ppending_recvframe_queue->lock);
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);
2033 /* s2. check if winstart_b(indicate_seq) needs to been updated */
2034 if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
2038 /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
2039 if (!enqueue_reorder_recvframe23a(preorder_ctrl, prframe)) {
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
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 =>
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);
2061 spin_unlock_bh(&ppending_recvframe_queue->lock);
2062 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
2068 spin_unlock_bh(&ppending_recvframe_queue->lock);
2072 void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext)
2074 struct recv_reorder_ctrl *preorder_ctrl;
2075 struct rtw_adapter *padapter;
2076 struct rtw_queue *ppending_recvframe_queue;
2078 preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
2079 padapter = preorder_ctrl->padapter;
2080 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2082 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
2086 /* DBG_8723A("+rtw_reordering_ctrl_timeout_handler23a() =>\n"); */
2088 spin_lock_bh(&ppending_recvframe_queue->lock);
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));
2095 spin_unlock_bh(&ppending_recvframe_queue->lock);
2098 int process_recv_indicatepkts(struct rtw_adapter *padapter,
2099 struct recv_frame *prframe);
2100 int process_recv_indicatepkts(struct rtw_adapter *padapter,
2101 struct recv_frame *prframe)
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;
2109 if (phtpriv->ht_option == true) { /* B/G/N Mode */
2110 /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
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)) {
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");
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);
2135 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2136 "@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n");
2138 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2139 "recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
2140 padapter->bDriverStopped,
2141 padapter->bSurpriseRemoved);
2151 static int recv_func_prehandle(struct rtw_adapter *padapter,
2152 struct recv_frame *rframe)
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);
2169 static int recv_func_posthandle(struct rtw_adapter *padapter,
2170 struct recv_frame *prframe)
2173 struct recv_frame *orig_prframe = prframe;
2174 struct recv_priv *precvpriv = &padapter->recvpriv;
2177 prframe = decryptor(padapter, prframe);
2178 if (prframe == NULL) {
2179 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2180 "decryptor: drop pkt\n");
2182 goto _recv_data_drop;
2185 prframe = recvframe_chk_defrag23a(padapter, prframe);
2187 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2188 "recvframe_chk_defrag23a: drop pkt\n");
2189 goto _recv_data_drop;
2193 * Pull off crypto headers
2195 if (prframe->attrib.iv_len > 0) {
2196 skb_pull(prframe->pkt, prframe->attrib.iv_len);
2199 if (prframe->attrib.icv_len > 0) {
2200 skb_trim(prframe->pkt,
2201 prframe->pkt->len - prframe->attrib.icv_len);
2204 prframe = portctrl(padapter, prframe);
2206 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2207 "portctrl: drop pkt\n");
2209 goto _recv_data_drop;
2212 count_rx_stats(padapter, prframe, NULL);
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;
2224 precvpriv->rx_drop++;
2228 int rtw_recv_entry23a(struct recv_frame *rframe)
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;
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;
2242 while ((pending_frame = rtw_alloc_recvframe23a(&padapter->recvpriv.uc_swdec_pending_queue))) {
2243 r = recv_func_posthandle(padapter, pending_frame);
2245 DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
2249 ret = recv_func_prehandle(padapter, rframe);
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__);
2264 ret = recv_func_posthandle(padapter, rframe);
2266 recvpriv->rx_pkts++;
2273 void rtw_signal_stat_timer_hdl23a(unsigned long data)
2275 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
2276 struct recv_priv *recvpriv = &adapter->recvpriv;
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 */
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;
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;
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;
2309 tmp_s = tmp_s / _alpha + 1;
2311 tmp_s = tmp_s / _alpha;
2315 tmp_q = avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual;
2317 tmp_q = tmp_q / _alpha + 1;
2319 tmp_q = tmp_q / _alpha;
2323 recvpriv->signal_strength = tmp_s;
2324 recvpriv->signal_qual = tmp_q;
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,
2333 rtw_set_signal_stat_timer(recvpriv);