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 = NULL;
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 = NULL;
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);
1558 memcpy(ptr + 12, &len, 2);
1565 /* perform defrag */
1566 struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1567 struct rtw_queue *defrag_q);
1568 struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1569 struct rtw_queue *defrag_q)
1571 struct list_head *plist, *phead, *ptmp;
1572 u8 *data, wlanhdr_offset;
1574 struct recv_frame *pnfhdr;
1575 struct recv_frame *prframe, *pnextrframe;
1576 struct rtw_queue *pfree_recv_queue;
1577 struct sk_buff *skb;
1582 pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
1584 phead = get_list_head(defrag_q);
1585 plist = phead->next;
1586 prframe = container_of(plist, struct recv_frame, list);
1587 list_del_init(&prframe->list);
1590 if (curfragnum != prframe->attrib.frag_num) {
1591 /* the first fragment number must be 0 */
1592 /* free the whole queue */
1593 rtw_free_recvframe23a(prframe);
1594 rtw_free_recvframe23a_queue(defrag_q);
1601 phead = get_list_head(defrag_q);
1603 data = prframe->pkt->data;
1605 list_for_each_safe(plist, ptmp, phead) {
1606 pnfhdr = container_of(plist, struct recv_frame, list);
1607 pnextrframe = (struct recv_frame *)pnfhdr;
1608 /* check the fragment sequence (2nd ~n fragment frame) */
1610 if (curfragnum != pnfhdr->attrib.frag_num) {
1611 /* the fragment number must be increasing
1613 /* release the defrag_q & prframe */
1614 rtw_free_recvframe23a(prframe);
1615 rtw_free_recvframe23a_queue(defrag_q);
1621 /* copy the 2nd~n fragment frame's payload to the
1623 /* get the 2nd~last fragment frame's payload */
1625 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1627 skb_pull(pnfhdr->pkt, wlanhdr_offset);
1629 /* append to first fragment frame's tail
1630 (if privacy frame, pull the ICV) */
1632 skb_trim(skb, skb->len - prframe->attrib.icv_len);
1634 memcpy(skb_tail_pointer(skb), pnfhdr->pkt->data,
1637 skb_put(skb, pnfhdr->pkt->len);
1639 prframe->attrib.icv_len = pnfhdr->attrib.icv_len;
1642 /* free the defrag_q queue and return the prframe */
1643 rtw_free_recvframe23a_queue(defrag_q);
1645 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1646 "Performance defrag!!!!!\n");
1653 /* check if need to defrag, if needed queue the frame to defrag_q */
1654 struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1655 struct recv_frame *precv_frame)
1660 struct recv_frame *pfhdr;
1661 struct sta_info *psta;
1662 struct sta_priv *pstapriv;
1663 struct list_head *phead;
1664 struct recv_frame *prtnframe = NULL;
1665 struct rtw_queue *pfree_recv_queue, *pdefrag_q;
1669 pstapriv = &padapter->stapriv;
1671 pfhdr = precv_frame;
1673 pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1675 /* need to define struct of wlan header frame ctrl */
1676 ismfrag = pfhdr->attrib.mfrag;
1677 fragnum = pfhdr->attrib.frag_num;
1679 psta_addr = pfhdr->attrib.ta;
1680 psta = rtw_get_stainfo23a(pstapriv, psta_addr);
1682 struct ieee80211_hdr *hdr =
1683 (struct ieee80211_hdr *) pfhdr->pkt->data;
1684 if (!ieee80211_is_data(hdr->frame_control)) {
1685 psta = rtw_get_bcmc_stainfo23a(padapter);
1686 pdefrag_q = &psta->sta_recvpriv.defrag_q;
1690 pdefrag_q = &psta->sta_recvpriv.defrag_q;
1692 if ((ismfrag == 0) && (fragnum == 0)) {
1693 prtnframe = precv_frame;/* isn't a fragment frame */
1697 /* 0~(n-1) fragment frame */
1698 /* enqueue to defraf_g */
1699 if (pdefrag_q != NULL) {
1701 /* the first fragment */
1702 if (!list_empty(&pdefrag_q->queue)) {
1703 /* free current defrag_q */
1704 rtw_free_recvframe23a_queue(pdefrag_q);
1708 /* Then enqueue the 0~(n-1) fragment into the
1711 /* spin_lock(&pdefrag_q->lock); */
1712 phead = get_list_head(pdefrag_q);
1713 list_add_tail(&pfhdr->list, phead);
1714 /* spin_unlock(&pdefrag_q->lock); */
1716 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1717 "Enqueuq: ismfrag = %d, fragnum = %d\n",
1723 /* can't find this ta's defrag_queue,
1724 so free this recv_frame */
1725 rtw_free_recvframe23a(precv_frame);
1727 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1728 "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
1733 if ((ismfrag == 0) && (fragnum != 0)) {
1734 /* the last fragment frame */
1735 /* enqueue the last fragment */
1736 if (pdefrag_q != NULL) {
1737 /* spin_lock(&pdefrag_q->lock); */
1738 phead = get_list_head(pdefrag_q);
1739 list_add_tail(&pfhdr->list, phead);
1740 /* spin_unlock(&pdefrag_q->lock); */
1742 /* call recvframe_defrag to defrag */
1743 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1744 "defrag: ismfrag = %d, fragnum = %d\n",
1746 precv_frame = recvframe_defrag(padapter, pdefrag_q);
1747 prtnframe = precv_frame;
1749 /* can't find this ta's defrag_queue,
1750 so free this recv_frame */
1751 rtw_free_recvframe23a(precv_frame);
1753 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1754 "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
1760 if ((prtnframe != NULL) && (prtnframe->attrib.privacy)) {
1761 /* after defrag we must check tkip mic code */
1762 if (recvframe_chkmic(padapter, prtnframe) == _FAIL) {
1763 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1764 "recvframe_chkmic(padapter, prtnframe) ==_FAIL\n");
1765 rtw_free_recvframe23a(prtnframe);
1775 int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe);
1776 int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe)
1778 struct rx_pkt_attrib *pattrib;
1779 struct sk_buff *skb, *sub_skb;
1780 struct sk_buff_head skb_list;
1782 pattrib = &prframe->attrib;
1785 skb_pull(skb, prframe->attrib.hdrlen);
1786 __skb_queue_head_init(&skb_list);
1788 ieee80211_amsdu_to_8023s(skb, &skb_list, NULL, 0, 0, false);
1790 while (!skb_queue_empty(&skb_list)) {
1791 sub_skb = __skb_dequeue(&skb_list);
1793 sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
1794 sub_skb->dev = padapter->pnetdev;
1796 sub_skb->ip_summed = CHECKSUM_NONE;
1801 prframe->pkt = NULL;
1802 rtw_free_recvframe23a(prframe);
1806 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
1807 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
1809 u8 wsize = preorder_ctrl->wsize_b;
1810 u16 wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;
1812 /* Rx Reorder initialize condition. */
1813 if (preorder_ctrl->indicate_seq == 0xFFFF)
1814 preorder_ctrl->indicate_seq = seq_num;
1816 /* Drop out the packet which SeqNum is smaller than WinStart */
1817 if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
1821 /* Sliding window manipulation. Conditions includes: */
1822 /* 1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
1823 /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */
1825 if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
1826 preorder_ctrl->indicate_seq =
1827 (preorder_ctrl->indicate_seq + 1) & 0xFFF;
1828 } else if (SN_LESS(wend, seq_num)) {
1829 /* boundary situation, when seq_num cross 0xFFF */
1830 if (seq_num >= (wsize - 1))
1831 preorder_ctrl->indicate_seq = seq_num + 1 -wsize;
1833 preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
1838 static int enqueue_reorder_recvframe23a(struct recv_reorder_ctrl *preorder_ctrl,
1839 struct recv_frame *prframe)
1841 struct rx_pkt_attrib *pattrib = &prframe->attrib;
1842 struct rtw_queue *ppending_recvframe_queue;
1843 struct list_head *phead, *plist, *ptmp;
1844 struct recv_frame *hdr;
1845 struct rx_pkt_attrib *pnextattrib;
1847 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1848 /* DbgPrint("+enqueue_reorder_recvframe23a()\n"); */
1850 /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1851 /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1853 phead = get_list_head(ppending_recvframe_queue);
1855 list_for_each_safe(plist, ptmp, phead) {
1856 hdr = container_of(plist, struct recv_frame, list);
1857 pnextattrib = &hdr->attrib;
1859 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) {
1861 } else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
1862 /* Duplicate entry is found!! Do not insert current entry. */
1864 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1870 /* DbgPrint("enqueue_reorder_recvframe23a():while\n"); */
1873 /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1874 /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1876 list_del_init(&prframe->list);
1878 list_add_tail(&prframe->list, plist);
1880 /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1881 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1886 int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1887 struct recv_reorder_ctrl *preorder_ctrl,
1889 int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1890 struct recv_reorder_ctrl *preorder_ctrl,
1893 /* u8 bcancelled; */
1894 struct list_head *phead, *plist;
1895 struct recv_frame *prframe;
1896 struct rx_pkt_attrib *pattrib;
1898 int bPktInBuf = false;
1899 struct recv_priv *precvpriv;
1900 struct rtw_queue *ppending_recvframe_queue;
1902 precvpriv = &padapter->recvpriv;
1903 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1904 /* DbgPrint("+recv_indicatepkts_in_order\n"); */
1906 /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1907 /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1909 phead = get_list_head(ppending_recvframe_queue);
1910 plist = phead->next;
1912 /* Handling some condition for forced indicate case. */
1914 if (list_empty(phead)) {
1915 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1916 /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1920 prframe = container_of(plist, struct recv_frame, list);
1921 pattrib = &prframe->attrib;
1922 preorder_ctrl->indicate_seq = pattrib->seq_num;
1925 /* Prepare indication list and indication. */
1926 /* Check if there is any packet need indicate. */
1927 while (!list_empty(phead)) {
1929 prframe = container_of(plist, struct recv_frame, list);
1930 pattrib = &prframe->attrib;
1932 if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
1933 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1934 "recv_indicatepkts_in_order: indicate =%d seq =%d amsdu =%d\n",
1935 preorder_ctrl->indicate_seq,
1936 pattrib->seq_num, pattrib->amsdu);
1938 plist = plist->next;
1939 list_del_init(&prframe->list);
1941 if (SN_EQUAL(preorder_ctrl->indicate_seq,
1942 pattrib->seq_num)) {
1943 preorder_ctrl->indicate_seq =
1944 (preorder_ctrl->indicate_seq + 1)&0xFFF;
1947 if (!pattrib->amsdu) {
1948 if ((padapter->bDriverStopped == false) &&
1949 (padapter->bSurpriseRemoved == false)) {
1950 rtw_recv_indicatepkt23a(padapter, prframe);
1953 if (amsdu_to_msdu(padapter, prframe) !=
1955 rtw_free_recvframe23a(prframe);
1958 /* Update local variables. */
1966 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
1969 /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1970 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1975 int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
1976 struct recv_frame *prframe);
1977 int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
1978 struct recv_frame *prframe)
1980 int retval = _SUCCESS;
1981 struct rx_pkt_attrib *pattrib;
1982 struct recv_reorder_ctrl *preorder_ctrl;
1983 struct rtw_queue *ppending_recvframe_queue;
1985 pattrib = &prframe->attrib;
1986 preorder_ctrl = prframe->preorder_ctrl;
1987 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1989 if (!pattrib->amsdu) {
1991 wlanhdr_to_ethhdr(prframe);
1993 if ((pattrib->qos!= 1) || (pattrib->eth_type == ETH_P_ARP) ||
1994 (pattrib->ack_policy != 0)) {
1995 if ((padapter->bDriverStopped == false) &&
1996 (padapter->bSurpriseRemoved == false)) {
1997 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1998 "@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n");
2000 rtw_recv_indicatepkt23a(padapter, prframe);
2007 if (preorder_ctrl->enable == false) {
2008 /* indicate this recv_frame */
2009 preorder_ctrl->indicate_seq = pattrib->seq_num;
2010 rtw_recv_indicatepkt23a(padapter, prframe);
2012 preorder_ctrl->indicate_seq =
2013 (preorder_ctrl->indicate_seq + 1) % 4096;
2017 /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
2018 if (preorder_ctrl->enable == false) {
2019 preorder_ctrl->indicate_seq = pattrib->seq_num;
2020 retval = amsdu_to_msdu(padapter, prframe);
2022 preorder_ctrl->indicate_seq =
2023 (preorder_ctrl->indicate_seq + 1) % 4096;
2028 spin_lock_bh(&ppending_recvframe_queue->lock);
2030 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2031 "recv_indicatepkt_reorder: indicate =%d seq =%d\n",
2032 preorder_ctrl->indicate_seq, pattrib->seq_num);
2034 /* s2. check if winstart_b(indicate_seq) needs to been updated */
2035 if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
2039 /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
2040 if (!enqueue_reorder_recvframe23a(preorder_ctrl, prframe)) {
2045 /* Indication process. */
2046 /* After Packet dropping and Sliding Window shifting as above,
2047 we can now just indicate the packets */
2048 /* with the SeqNum smaller than latest WinStart and buffer
2051 /* For Rx Reorder condition: */
2052 /* 1. All packets with SeqNum smaller than WinStart => Indicate */
2053 /* 2. All packets with SeqNum larger than or equal to WinStart =>
2057 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) {
2058 mod_timer(&preorder_ctrl->reordering_ctrl_timer,
2059 jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
2060 spin_unlock_bh(&ppending_recvframe_queue->lock);
2062 spin_unlock_bh(&ppending_recvframe_queue->lock);
2063 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
2069 spin_unlock_bh(&ppending_recvframe_queue->lock);
2073 void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext)
2075 struct recv_reorder_ctrl *preorder_ctrl;
2076 struct rtw_adapter *padapter;
2077 struct rtw_queue *ppending_recvframe_queue;
2079 preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
2080 padapter = preorder_ctrl->padapter;
2081 ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2083 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
2087 /* DBG_8723A("+rtw_reordering_ctrl_timeout_handler23a() =>\n"); */
2089 spin_lock_bh(&ppending_recvframe_queue->lock);
2091 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true) {
2092 mod_timer(&preorder_ctrl->reordering_ctrl_timer,
2093 jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
2096 spin_unlock_bh(&ppending_recvframe_queue->lock);
2099 int process_recv_indicatepkts(struct rtw_adapter *padapter,
2100 struct recv_frame *prframe);
2101 int process_recv_indicatepkts(struct rtw_adapter *padapter,
2102 struct recv_frame *prframe)
2104 int retval = _SUCCESS;
2105 /* struct recv_priv *precvpriv = &padapter->recvpriv; */
2106 /* struct rx_pkt_attrib *pattrib = &prframe->attrib; */
2107 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2108 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2110 if (phtpriv->ht_option == true) { /* B/G/N Mode */
2111 /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
2113 /* including perform A-MPDU Rx Ordering Buffer Control */
2114 if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
2115 if ((padapter->bDriverStopped == false) &&
2116 (padapter->bSurpriseRemoved == false)) {
2121 } else { /* B/G mode */
2122 retval = wlanhdr_to_ethhdr(prframe);
2123 if (retval != _SUCCESS) {
2124 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2125 "wlanhdr_to_ethhdr: drop pkt\n");
2129 if ((padapter->bDriverStopped == false) &&
2130 (padapter->bSurpriseRemoved == false)) {
2131 /* indicate this recv_frame */
2132 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2133 "@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n");
2134 rtw_recv_indicatepkt23a(padapter, prframe);
2136 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2137 "@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n");
2139 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2140 "recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
2141 padapter->bDriverStopped,
2142 padapter->bSurpriseRemoved);
2152 static int recv_func_prehandle(struct rtw_adapter *padapter,
2153 struct recv_frame *rframe)
2157 /* check the frame crtl field and decache */
2158 ret = validate_recv_frame(padapter, rframe);
2159 if (ret != _SUCCESS) {
2160 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
2161 "recv_func: validate_recv_frame fail! drop pkt\n");
2162 rtw_free_recvframe23a(rframe);
2170 static int recv_func_posthandle(struct rtw_adapter *padapter,
2171 struct recv_frame *prframe)
2174 struct recv_frame *orig_prframe = prframe;
2175 struct recv_priv *precvpriv = &padapter->recvpriv;
2178 prframe = decryptor(padapter, prframe);
2179 if (prframe == NULL) {
2180 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2181 "decryptor: drop pkt\n");
2183 goto _recv_data_drop;
2186 prframe = recvframe_chk_defrag23a(padapter, prframe);
2188 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2189 "recvframe_chk_defrag23a: drop pkt\n");
2190 goto _recv_data_drop;
2194 * Pull off crypto headers
2196 if (prframe->attrib.iv_len > 0) {
2197 skb_pull(prframe->pkt, prframe->attrib.iv_len);
2200 if (prframe->attrib.icv_len > 0) {
2201 skb_trim(prframe->pkt,
2202 prframe->pkt->len - prframe->attrib.icv_len);
2205 prframe = portctrl(padapter, prframe);
2207 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2208 "portctrl: drop pkt\n");
2210 goto _recv_data_drop;
2213 count_rx_stats(padapter, prframe, NULL);
2215 ret = process_recv_indicatepkts(padapter, prframe);
2216 if (ret != _SUCCESS) {
2217 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2218 "recv_func: process_recv_indicatepkts fail!\n");
2219 rtw_free_recvframe23a(orig_prframe);/* free this recv_frame */
2220 goto _recv_data_drop;
2225 precvpriv->rx_drop++;
2229 int rtw_recv_entry23a(struct recv_frame *rframe)
2232 struct rtw_adapter *padapter = rframe->adapter;
2233 struct rx_pkt_attrib *prxattrib = &rframe->attrib;
2234 struct recv_priv *recvpriv = &padapter->recvpriv;
2235 struct security_priv *psecuritypriv = &padapter->securitypriv;
2236 struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2238 /* check if need to handle uc_swdec_pending_queue*/
2239 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2240 psecuritypriv->busetkipkey) {
2241 struct recv_frame *pending_frame;
2243 while ((pending_frame = rtw_alloc_recvframe23a(&padapter->recvpriv.uc_swdec_pending_queue))) {
2244 r = recv_func_posthandle(padapter, pending_frame);
2246 DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
2250 ret = recv_func_prehandle(padapter, rframe);
2252 if (ret == _SUCCESS) {
2253 /* check if need to enqueue into uc_swdec_pending_queue*/
2254 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2255 !is_multicast_ether_addr(prxattrib->ra) &&
2256 prxattrib->encrypt > 0 &&
2257 (prxattrib->bdecrypted == 0) &&
2258 !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) &&
2259 !psecuritypriv->busetkipkey) {
2260 rtw_enqueue_recvframe23a(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
2261 DBG_8723A("%s: no key, enqueue uc_swdec_pending_queue\n", __func__);
2265 ret = recv_func_posthandle(padapter, rframe);
2267 recvpriv->rx_pkts++;
2274 void rtw_signal_stat_timer_hdl23a(unsigned long data)
2276 struct rtw_adapter *adapter = (struct rtw_adapter *)data;
2277 struct recv_priv *recvpriv = &adapter->recvpriv;
2280 u8 avg_signal_strength = 0;
2281 u8 avg_signal_qual = 0;
2282 u32 num_signal_strength = 0;
2283 u32 num_signal_qual = 0;
2284 u8 _alpha = 3; /* this value is based on converging_constant = 5000 */
2285 /* and sampling_interval = 1000 */
2287 if (recvpriv->signal_strength_data.update_req == 0) {
2288 /* update_req is clear, means we got rx */
2289 avg_signal_strength = recvpriv->signal_strength_data.avg_val;
2290 num_signal_strength = recvpriv->signal_strength_data.total_num;
2291 /* after avg_vals are acquired, we can re-stat */
2292 /* the signal values */
2293 recvpriv->signal_strength_data.update_req = 1;
2296 if (recvpriv->signal_qual_data.update_req == 0) {
2297 /* update_req is clear, means we got rx */
2298 avg_signal_qual = recvpriv->signal_qual_data.avg_val;
2299 num_signal_qual = recvpriv->signal_qual_data.total_num;
2300 /* after avg_vals are acquired, we can re-stat */
2301 /*the signal values */
2302 recvpriv->signal_qual_data.update_req = 1;
2305 /* update value of signal_strength, rssi, signal_qual */
2306 if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
2307 tmp_s = avg_signal_strength + (_alpha - 1) *
2308 recvpriv->signal_strength;
2310 tmp_s = tmp_s / _alpha + 1;
2312 tmp_s = tmp_s / _alpha;
2316 tmp_q = avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual;
2318 tmp_q = tmp_q / _alpha + 1;
2320 tmp_q = tmp_q / _alpha;
2324 recvpriv->signal_strength = tmp_s;
2325 recvpriv->signal_qual = tmp_q;
2327 DBG_8723A("%s signal_strength:%3u, signal_qual:%3u, "
2328 "num_signal_strength:%u, num_signal_qual:%u\n",
2329 __func__, recvpriv->signal_strength,
2330 recvpriv->signal_qual, num_signal_strength,
2334 rtw_set_signal_stat_timer(recvpriv);