1 /******************************************************************************
3 * Copyright(c) 2007 - 2017 Realtek Corporation.
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 *****************************************************************************/
17 #include <drv_types.h>
20 #if defined(PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
22 #error "Shall be Linux or Windows, but not both!\n"
27 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
28 static void rtw_signal_stat_timer_hdl(void *ctx);
31 SIGNAL_STAT_CALC_PROFILE_0 = 0,
32 SIGNAL_STAT_CALC_PROFILE_1,
33 SIGNAL_STAT_CALC_PROFILE_MAX
36 u8 signal_stat_calc_profile[SIGNAL_STAT_CALC_PROFILE_MAX][2] = {
37 {4, 1}, /* Profile 0 => pre_stat : curr_stat = 4 : 1 */
38 {3, 7} /* Profile 1 => pre_stat : curr_stat = 3 : 7 */
41 #ifndef RTW_SIGNAL_STATE_CALC_PROFILE
42 #define RTW_SIGNAL_STATE_CALC_PROFILE SIGNAL_STAT_CALC_PROFILE_1
45 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
47 u8 rtw_bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
48 u8 rtw_rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
49 static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
50 static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
52 static u8 SNAP_ETH_TYPE_TDLS[2] = {0x89, 0x0d};
55 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
60 _rtw_memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
62 _rtw_spinlock_init(&psta_recvpriv->lock);
64 /* for(i=0; i<MAX_RX_NUMBLKS; i++) */
65 /* _rtw_init_queue(&psta_recvpriv->blk_strms[i]); */
67 _rtw_init_queue(&psta_recvpriv->defrag_q);
72 sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter)
76 union recv_frame *precvframe;
80 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc(). */
81 /* _rtw_memset((unsigned char *)precvpriv, 0, sizeof (struct recv_priv)); */
83 _rtw_spinlock_init(&precvpriv->lock);
85 #ifdef CONFIG_RECV_THREAD_MODE
86 _rtw_init_sema(&precvpriv->recv_sema, 0);
90 _rtw_init_queue(&precvpriv->free_recv_queue);
91 _rtw_init_queue(&precvpriv->recv_pending_queue);
92 _rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
94 precvpriv->adapter = padapter;
96 precvpriv->free_recvframe_cnt = NR_RECVFRAME;
98 precvpriv->sink_udpport = 0;
99 precvpriv->pre_rtp_rxseq = 0;
100 precvpriv->cur_rtp_rxseq = 0;
102 #ifdef DBG_RX_SIGNAL_DISPLAY_RAW_DATA
103 precvpriv->store_law_data_flag = 1;
105 precvpriv->store_law_data_flag = 0;
108 rtw_os_recv_resource_init(precvpriv, padapter);
110 precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
112 if (precvpriv->pallocated_frame_buf == NULL) {
116 /* _rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); */
118 precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
119 /* precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - */
120 /* ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); */
122 precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
125 for (i = 0; i < NR_RECVFRAME ; i++) {
126 _rtw_init_listhead(&(precvframe->u.list));
128 rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
130 res = rtw_os_recv_resource_alloc(padapter, precvframe);
132 precvframe->u.hdr.len = 0;
134 precvframe->u.hdr.adapter = padapter;
139 #ifdef CONFIG_USB_HCI
141 ATOMIC_SET(&(precvpriv->rx_pending_cnt), 1);
143 _rtw_init_sema(&precvpriv->allrxreturnevt, 0);
147 res = rtw_hal_init_recv_priv(padapter);
149 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
150 rtw_init_timer(&precvpriv->signal_stat_timer, padapter, rtw_signal_stat_timer_hdl, padapter);
152 precvpriv->signal_stat_sampling_interval = 2000; /* ms */
153 /* precvpriv->signal_stat_converging_constant = 5000; */ /* ms */
155 rtw_set_signal_stat_timer(precvpriv);
156 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
165 void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv);
166 void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv)
168 _rtw_spinlock_free(&precvpriv->lock);
169 #ifdef CONFIG_RECV_THREAD_MODE
170 _rtw_free_sema(&precvpriv->recv_sema);
173 _rtw_spinlock_free(&precvpriv->free_recv_queue.lock);
174 _rtw_spinlock_free(&precvpriv->recv_pending_queue.lock);
176 _rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock);
178 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
179 _rtw_spinlock_free(&precvpriv->recv_buf_pending_queue.lock);
180 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
183 void _rtw_free_recv_priv(struct recv_priv *precvpriv)
185 _adapter *padapter = precvpriv->adapter;
188 rtw_free_uc_swdec_pending_queue(padapter);
190 rtw_mfree_recv_priv_lock(precvpriv);
192 rtw_os_recv_resource_free(precvpriv);
194 if (precvpriv->pallocated_frame_buf)
195 rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
197 rtw_hal_free_recv_priv(padapter);
202 bool rtw_rframe_del_wfd_ie(union recv_frame *rframe, u8 ies_offset)
204 #define DBG_RFRAME_DEL_WFD_IE 0
205 u8 *ies = rframe->u.hdr.rx_data + sizeof(struct rtw_ieee80211_hdr_3addr) + ies_offset;
206 uint ies_len_ori = rframe->u.hdr.len - (ies - rframe->u.hdr.rx_data);
209 ies_len = rtw_del_wfd_ie(ies, ies_len_ori, DBG_RFRAME_DEL_WFD_IE ? __func__ : NULL);
210 rframe->u.hdr.len -= ies_len_ori - ies_len;
212 return ies_len_ori != ies_len;
215 union recv_frame *_rtw_alloc_recvframe(_queue *pfree_recv_queue)
218 union recv_frame *precvframe;
219 _list *plist, *phead;
221 struct recv_priv *precvpriv;
223 if (_rtw_queue_empty(pfree_recv_queue) == _TRUE)
226 phead = get_list_head(pfree_recv_queue);
228 plist = get_next(phead);
230 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
232 rtw_list_delete(&precvframe->u.hdr.list);
233 padapter = precvframe->u.hdr.adapter;
234 if (padapter != NULL) {
235 precvpriv = &padapter->recvpriv;
236 if (pfree_recv_queue == &precvpriv->free_recv_queue)
237 precvpriv->free_recvframe_cnt--;
246 union recv_frame *rtw_alloc_recvframe(_queue *pfree_recv_queue)
249 union recv_frame *precvframe;
251 _enter_critical_bh(&pfree_recv_queue->lock, &irqL);
253 precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
255 _exit_critical_bh(&pfree_recv_queue->lock, &irqL);
260 void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv)
262 /* Perry: This can be removed */
263 _rtw_init_listhead(&precvframe->u.hdr.list);
265 precvframe->u.hdr.len = 0;
268 int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue)
271 _adapter *padapter = precvframe->u.hdr.adapter;
272 struct recv_priv *precvpriv = &padapter->recvpriv;
275 #ifdef CONFIG_CONCURRENT_MODE
276 padapter = GET_PRIMARY_ADAPTER(padapter);
277 precvpriv = &padapter->recvpriv;
278 pfree_recv_queue = &precvpriv->free_recv_queue;
279 precvframe->u.hdr.adapter = padapter;
283 rtw_os_free_recvframe(precvframe);
286 _enter_critical_bh(&pfree_recv_queue->lock, &irqL);
288 rtw_list_delete(&(precvframe->u.hdr.list));
290 precvframe->u.hdr.len = 0;
292 rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
294 if (padapter != NULL) {
295 if (pfree_recv_queue == &precvpriv->free_recv_queue)
296 precvpriv->free_recvframe_cnt++;
299 _exit_critical_bh(&pfree_recv_queue->lock, &irqL);
309 sint _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
312 _adapter *padapter = precvframe->u.hdr.adapter;
313 struct recv_priv *precvpriv = &padapter->recvpriv;
316 /* _rtw_init_listhead(&(precvframe->u.hdr.list)); */
317 rtw_list_delete(&(precvframe->u.hdr.list));
320 rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue));
322 if (padapter != NULL) {
323 if (queue == &precvpriv->free_recv_queue)
324 precvpriv->free_recvframe_cnt++;
331 sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
336 /* _spinlock(&pfree_recv_queue->lock); */
337 _enter_critical_bh(&queue->lock, &irqL);
338 ret = _rtw_enqueue_recvframe(precvframe, queue);
339 /* _rtw_spinunlock(&pfree_recv_queue->lock); */
340 _exit_critical_bh(&queue->lock, &irqL);
346 sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
348 return rtw_free_recvframe(precvframe, queue);
356 caller : defrag ; recvframe_chk_defrag in recv_thread (passive)
357 pframequeue: defrag_queue : will be accessed in recv_thread (passive)
359 using spinlock to protect
363 void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue)
365 union recv_frame *precvframe;
366 _list *plist, *phead;
368 _rtw_spinlock(&pframequeue->lock);
370 phead = get_list_head(pframequeue);
371 plist = get_next(phead);
373 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
374 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
376 plist = get_next(plist);
378 /* rtw_list_delete(&precvframe->u.hdr.list); */ /* will do this in rtw_free_recvframe() */
380 rtw_free_recvframe(precvframe, pfree_recv_queue);
383 _rtw_spinunlock(&pframequeue->lock);
388 u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter)
391 union recv_frame *pending_frame;
392 while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
393 rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
398 RTW_INFO(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt);
404 sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue)
408 _enter_critical_bh(&queue->lock, &irqL);
410 rtw_list_delete(&precvbuf->list);
411 rtw_list_insert_head(&precvbuf->list, get_list_head(queue));
413 _exit_critical_bh(&queue->lock, &irqL);
418 sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue)
421 #ifdef CONFIG_SDIO_HCI
422 _enter_critical_bh(&queue->lock, &irqL);
424 _enter_critical_ex(&queue->lock, &irqL);
425 #endif/*#ifdef CONFIG_SDIO_HCI*/
427 rtw_list_delete(&precvbuf->list);
429 rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
430 #ifdef CONFIG_SDIO_HCI
431 _exit_critical_bh(&queue->lock, &irqL);
433 _exit_critical_ex(&queue->lock, &irqL);
434 #endif/*#ifdef CONFIG_SDIO_HCI*/
439 struct recv_buf *rtw_dequeue_recvbuf(_queue *queue)
442 struct recv_buf *precvbuf;
443 _list *plist, *phead;
445 #ifdef CONFIG_SDIO_HCI
446 _enter_critical_bh(&queue->lock, &irqL);
448 _enter_critical_ex(&queue->lock, &irqL);
449 #endif/*#ifdef CONFIG_SDIO_HCI*/
451 if (_rtw_queue_empty(queue) == _TRUE)
454 phead = get_list_head(queue);
456 plist = get_next(phead);
458 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
460 rtw_list_delete(&precvbuf->list);
464 #ifdef CONFIG_SDIO_HCI
465 _exit_critical_bh(&queue->lock, &irqL);
467 _exit_critical_ex(&queue->lock, &irqL);
468 #endif/*#ifdef CONFIG_SDIO_HCI*/
474 sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe);
475 sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe)
478 sint i, res = _SUCCESS;
481 u8 bmic_err = _FALSE, brpt_micerror = _TRUE;
482 u8 *pframe, *payload, *pframemic;
484 /* u8 *iv,rxdata_key_idx=0; */
485 struct sta_info *stainfo;
486 struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib;
487 struct security_priv *psecuritypriv = &adapter->securitypriv;
489 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
490 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
492 stainfo = rtw_get_stainfo(&adapter->stapriv , &prxattrib->ta[0]);
494 if (prxattrib->encrypt == _TKIP_) {
496 /* calculate mic code */
497 if (stainfo != NULL) {
498 if (IS_MCAST(prxattrib->ra)) {
499 /* mickey=&psecuritypriv->dot118021XGrprxmickey.skey[0]; */
500 /* iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; */
501 /* rxdata_key_idx =( ((iv[3])>>6)&0x3) ; */
502 mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
504 /* RTW_INFO("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d),pmlmeinfo->key_index(%d) ,recv key_id(%d)\n", */
505 /* psecuritypriv->dot118021XGrpKeyid,pmlmeinfo->key_index,rxdata_key_idx); */
507 if (psecuritypriv->binstallGrpkey == _FALSE) {
509 RTW_INFO("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
513 mickey = &stainfo->dot11tkiprxmickey.skey[0];
516 datalen = precvframe->u.hdr.len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8; /* icv_len included the mic code */
517 pframe = precvframe->u.hdr.rx_data;
518 payload = pframe + prxattrib->hdrlen + prxattrib->iv_len;
521 /* rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); */ /* care the length of the data */
523 rtw_seccalctkipmic(mickey, pframe, payload, datalen , &miccode[0], (unsigned char)prxattrib->priority); /* care the length of the data */
525 pframemic = payload + datalen;
529 for (i = 0; i < 8; i++) {
530 if (miccode[i] != *(pframemic + i)) {
536 if (bmic_err == _TRUE) {
540 /* double check key_index for some timing issue , */
541 /* cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
542 if ((IS_MCAST(prxattrib->ra) == _TRUE) && (prxattrib->key_index != pmlmeinfo->key_index))
543 brpt_micerror = _FALSE;
545 if ((prxattrib->bdecrypted == _TRUE) && (brpt_micerror == _TRUE)) {
546 rtw_handle_tkip_mic_err(adapter, stainfo, (u8)IS_MCAST(prxattrib->ra));
547 RTW_INFO(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
549 RTW_INFO(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
556 if ((psecuritypriv->bcheck_grpkey == _FALSE) && (IS_MCAST(prxattrib->ra) == _TRUE)) {
557 psecuritypriv->bcheck_grpkey = _TRUE;
563 recvframe_pull_tail(precvframe, 8);
574 /*#define DBG_RX_SW_DECRYPTOR*/
576 /* decrypt and set the ivlen,icvlen of the recv_frame */
577 union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame);
578 union recv_frame *decryptor(_adapter *padapter, union recv_frame *precv_frame)
581 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
582 struct security_priv *psecuritypriv = &padapter->securitypriv;
583 union recv_frame *return_packet = precv_frame;
587 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt);
590 if (prxattrib->encrypt > 0) {
591 u8 *iv = precv_frame->u.hdr.rx_data + prxattrib->hdrlen;
592 prxattrib->key_index = (((iv[3]) >> 6) & 0x3) ;
594 if (prxattrib->key_index > WEP_KEYS) {
595 RTW_INFO("prxattrib->key_index(%d) > WEP_KEYS\n", prxattrib->key_index);
597 switch (prxattrib->encrypt) {
600 prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
605 prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
611 if (prxattrib->encrypt && !prxattrib->bdecrypted) {
612 if (GetFrameType(get_recvframe_data(precv_frame)) == WIFI_DATA
613 #ifdef CONFIG_CONCURRENT_MODE
614 && !IS_MCAST(prxattrib->ra) /* bc/mc packets may use sw decryption for concurrent mode */
617 psecuritypriv->hw_decrypted = _FALSE;
619 #ifdef DBG_RX_SW_DECRYPTOR
620 RTW_INFO(ADPT_FMT" - sec_type:%s DO SW decryption\n",
621 ADPT_ARG(padapter), security_type_str(prxattrib->encrypt));
624 #ifdef DBG_RX_DECRYPTOR
625 RTW_INFO("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
628 prxattrib->bdecrypted,
630 psecuritypriv->hw_decrypted);
633 switch (prxattrib->encrypt) {
636 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep);
637 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
640 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip);
641 res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
644 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes);
645 res = rtw_aes_decrypt(padapter, (u8 *)precv_frame);
647 #ifdef CONFIG_WAPI_SUPPORT
649 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wapi);
650 rtw_sms4_decrypt(padapter, (u8 *)precv_frame);
656 } else if (prxattrib->bdecrypted == 1
657 && prxattrib->encrypt > 0
658 && (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_)
661 if ((prxstat->icv == 1) && (prxattrib->encrypt != _AES_)) {
662 psecuritypriv->hw_decrypted = _FALSE;
665 rtw_free_recvframe(precv_frame, &padapter->recvpriv.free_recv_queue);
667 return_packet = NULL;
672 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw);
674 psecuritypriv->hw_decrypted = _TRUE;
675 #ifdef DBG_RX_DECRYPTOR
676 RTW_INFO("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
679 prxattrib->bdecrypted,
681 psecuritypriv->hw_decrypted);
686 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown);
687 #ifdef DBG_RX_DECRYPTOR
688 RTW_INFO("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n",
691 prxattrib->bdecrypted,
693 psecuritypriv->hw_decrypted);
697 #ifdef CONFIG_RTW_MESH
700 && prxattrib->mesh_ctrl_present)
701 res = rtw_mesh_rx_validate_mctrl_non_amsdu(padapter, precv_frame);
705 rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
706 return_packet = NULL;
708 prxattrib->bdecrypted = _TRUE;
709 /* recvframe_chkmic(adapter, precv_frame); */ /* move to recvframme_defrag function */
712 return return_packet;
715 /* ###set the security information in the recv_frame */
716 union recv_frame *portctrl(_adapter *adapter, union recv_frame *precv_frame);
717 union recv_frame *portctrl(_adapter *adapter, union recv_frame *precv_frame)
719 u8 *psta_addr = NULL;
722 struct recv_frame_hdr *pfhdr;
723 struct sta_info *psta;
724 struct sta_priv *pstapriv ;
725 union recv_frame *prtnframe;
727 u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */
728 struct rx_pkt_attrib *pattrib;
731 pstapriv = &adapter->stapriv;
733 auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
735 ptr = get_recvframe_data(precv_frame);
736 pfhdr = &precv_frame->u.hdr;
737 pattrib = &pfhdr->attrib;
738 psta_addr = pattrib->ta;
742 psta = rtw_get_stainfo(pstapriv, psta_addr);
745 if (auth_alg == dot11AuthAlgrthm_8021X) {
746 if ((psta != NULL) && (psta->ieee8021x_blocked)) {
748 /* only accept EAPOL frame */
750 prtnframe = precv_frame;
753 ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
754 _rtw_memcpy(ðer_type, ptr, 2);
755 ether_type = ntohs((unsigned short)ether_type);
757 if (ether_type == eapol_type)
758 prtnframe = precv_frame;
760 /* free this frame */
761 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
766 /* check decryption status, and decrypt the frame if needed */
769 prtnframe = precv_frame;
770 /* check is the EAPOL frame or not (Rekey) */
771 /* if(ether_type == eapol_type){ */
774 /* prtnframe=precv_frame; */
778 prtnframe = precv_frame;
786 * Return true when PN is legal, otherwise false.
788 * 1. If old PN is 0, any PN is legal
791 #define PN_LESS_CHK(a, b) (((a-b) & 0x800000000000) != 0)
792 #define VALID_PN_CHK(new, old) (((old) == 0) || PN_LESS_CHK(old, new))
793 #define CCMPH_2_KEYID(ch) (((ch) & 0x00000000c0000000) >> 30)
794 sint recv_ucast_pn_decache(union recv_frame *precv_frame);
795 sint recv_ucast_pn_decache(union recv_frame *precv_frame)
797 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
798 struct sta_info *sta = precv_frame->u.hdr.psta;
799 struct stainfo_rxcache *prxcache = &sta->sta_recvpriv.rxcache;
800 u8 *pdata = precv_frame->u.hdr.rx_data;
801 sint tid = precv_frame->u.hdr.attrib.priority;
803 u64 curr_pn = 0, pkt_pn = 0;
808 if (pattrib->encrypt == _AES_) {
809 tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen));
810 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
811 tmp_iv_hdr = le64_to_cpu(*(u64*)prxcache->iv[tid]);
812 curr_pn = CCMPH_2_PN(tmp_iv_hdr);
814 if (!VALID_PN_CHK(pkt_pn, curr_pn)) {
817 prxcache->last_tid = tid;
818 _rtw_memcpy(prxcache->iv[tid],
819 (pdata + pattrib->hdrlen),
820 sizeof(prxcache->iv[tid]));
827 sint recv_bcast_pn_decache(union recv_frame *precv_frame);
828 sint recv_bcast_pn_decache(union recv_frame *precv_frame)
830 _adapter *padapter = precv_frame->u.hdr.adapter;
831 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
832 struct security_priv *psecuritypriv = &padapter->securitypriv;
833 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
834 u8 *pdata = precv_frame->u.hdr.rx_data;
836 u64 curr_pn = 0, pkt_pn = 0;
839 if ((pattrib->encrypt == _AES_) &&
840 (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)) {
842 tmp_iv_hdr = le64_to_cpu(*(u64*)(pdata + pattrib->hdrlen));
843 key_id = CCMPH_2_KEYID(tmp_iv_hdr);
844 pkt_pn = CCMPH_2_PN(tmp_iv_hdr);
846 curr_pn = le64_to_cpu(*(u64*)psecuritypriv->iv_seq[key_id]);
847 curr_pn &= 0x0000ffffffffffff;
849 if (!VALID_PN_CHK(pkt_pn, curr_pn))
852 *(u64*)psecuritypriv->iv_seq[key_id] = cpu_to_le64(pkt_pn);
858 sint recv_decache(union recv_frame *precv_frame)
860 struct sta_info *psta = precv_frame->u.hdr.psta;
861 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
862 _adapter *adapter = psta->padapter;
863 sint tid = pattrib->priority;
864 u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) |
865 (precv_frame->u.hdr.attrib.frag_num & 0xf);
872 if (IS_MCAST(pattrib->ra))
873 prxseq = &psta->sta_recvpriv.bmc_tid_rxseq[tid];
875 prxseq = &psta->sta_recvpriv.rxcache.tid_rxseq[tid];
877 if (IS_MCAST(pattrib->ra)) {
878 prxseq = &psta->sta_recvpriv.nonqos_bmc_rxseq;
880 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" nonqos bmc seq_num:%d\n"
881 , FUNC_ADPT_ARG(adapter), pattrib->seq_num);
885 prxseq = &psta->sta_recvpriv.nonqos_rxseq;
887 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" nonqos seq_num:%d\n"
888 , FUNC_ADPT_ARG(adapter), pattrib->seq_num);
893 if (seq_ctrl == *prxseq) {
894 /* for non-AMPDU case */
895 psta->sta_stats.duplicate_cnt++;
897 if (psta->sta_stats.duplicate_cnt % 100 == 0)
898 RTW_INFO("%s: tid=%u seq=%d frag=%d\n", __func__
899 , tid, precv_frame->u.hdr.attrib.seq_num
900 , precv_frame->u.hdr.attrib.frag_num);
902 #ifdef DBG_RX_DROP_FRAME
903 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv_decache _FAIL for sta="MAC_FMT"\n"
904 , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr));
913 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta)
915 #ifdef CONFIG_AP_MODE
916 unsigned char pwrbit;
917 u8 *ptr = precv_frame->u.hdr.rx_data;
919 pwrbit = GetPwrMgt(ptr);
922 if (!(psta->state & WIFI_SLEEP_STATE)) {
923 /* psta->state |= WIFI_SLEEP_STATE; */
924 /* rtw_tim_map_set(padapter, pstapriv->sta_dz_bitmap, BIT(psta->cmn.aid)); */
926 stop_sta_xmit(padapter, psta);
927 /* RTW_INFO_DUMP("to sleep, sta_dz_bitmap=", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len); */
930 if (psta->state & WIFI_SLEEP_STATE) {
931 /* psta->state ^= WIFI_SLEEP_STATE; */
932 /* rtw_tim_map_clear(padapter, pstapriv->sta_dz_bitmap, BIT(psta->cmn.aid)); */
934 wakeup_sta_to_xmit(padapter, psta);
935 /* RTW_INFO_DUMP("to wakeup, sta_dz_bitmap=", pstapriv->sta_dz_bitmap, pstapriv->aid_bmp_len); */
941 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame, struct sta_info *psta)
943 #ifdef CONFIG_AP_MODE
944 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
947 if (!(psta->tdls_sta_state & TDLS_LINKED_STATE)) {
948 #endif /* CONFIG_TDLS */
950 if (!psta->qos_option)
953 if (!(psta->qos_info & 0xf))
958 #endif /* CONFIG_TDLS */
960 if (psta->state & WIFI_SLEEP_STATE) {
963 switch (pattrib->priority) {
966 wmmps_ac = psta->uapsd_bk & BIT(1);
970 wmmps_ac = psta->uapsd_vi & BIT(1);
974 wmmps_ac = psta->uapsd_vo & BIT(1);
979 wmmps_ac = psta->uapsd_be & BIT(1);
984 if (psta->sleepq_ac_len > 0) {
985 /* process received triggered frame */
986 xmit_delivery_enabled_frames(padapter, psta);
988 /* issue one qos null frame with More data bit = 0 and the EOSP bit set (=1) */
989 issue_qos_nulldata(padapter, psta->cmn.mac_addr, (u16)pattrib->priority, 0, 0, 0);
1001 sint OnTDLS(_adapter *adapter, union recv_frame *precv_frame)
1003 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1004 sint ret = _SUCCESS;
1005 u8 *paction = get_recvframe_data(precv_frame);
1006 u8 category_field = 1;
1008 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a };
1009 #endif /* CONFIG_WFD */
1010 struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
1011 u8 *ptr = precv_frame->u.hdr.rx_data;
1012 struct sta_priv *pstapriv = &(adapter->stapriv);
1013 struct sta_info *ptdls_sta = NULL;
1015 /* point to action field */
1016 paction += pattrib->hdrlen
1023 RTW_INFO("[TDLS] Recv %s from "MAC_FMT" with SeqNum = %d\n", rtw_tdls_action_txt(*paction), MAC_ARG(pattrib->src), GetSequence(get_recvframe_data(precv_frame)));
1025 if (hal_chk_wl_func(adapter, WL_FUNC_TDLS) == _FALSE) {
1026 RTW_INFO("Ignore tdls frame since hal doesn't support tdls\n");
1031 if (rtw_is_tdls_enabled(adapter) == _FALSE) {
1032 RTW_INFO("recv tdls frame, "
1033 "but tdls haven't enabled\n");
1038 ptdls_sta = rtw_get_stainfo(pstapriv, get_sa(ptr));
1039 if (ptdls_sta == NULL) {
1041 case TDLS_SETUP_REQUEST:
1042 case TDLS_DISCOVERY_REQUEST:
1045 RTW_INFO("[TDLS] %s - Direct Link Peer = "MAC_FMT" not found for action = %d\n", __func__, MAC_ARG(get_sa(ptr)), *paction);
1052 case TDLS_SETUP_REQUEST:
1053 ret = On_TDLS_Setup_Req(adapter, precv_frame, ptdls_sta);
1055 case TDLS_SETUP_RESPONSE:
1056 ret = On_TDLS_Setup_Rsp(adapter, precv_frame, ptdls_sta);
1058 case TDLS_SETUP_CONFIRM:
1059 ret = On_TDLS_Setup_Cfm(adapter, precv_frame, ptdls_sta);
1062 ret = On_TDLS_Teardown(adapter, precv_frame, ptdls_sta);
1064 case TDLS_DISCOVERY_REQUEST:
1065 ret = On_TDLS_Dis_Req(adapter, precv_frame);
1067 case TDLS_PEER_TRAFFIC_INDICATION:
1068 ret = On_TDLS_Peer_Traffic_Indication(adapter, precv_frame, ptdls_sta);
1070 case TDLS_PEER_TRAFFIC_RESPONSE:
1071 ret = On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame, ptdls_sta);
1073 #ifdef CONFIG_TDLS_CH_SW
1074 case TDLS_CHANNEL_SWITCH_REQUEST:
1075 ret = On_TDLS_Ch_Switch_Req(adapter, precv_frame, ptdls_sta);
1077 case TDLS_CHANNEL_SWITCH_RESPONSE:
1078 ret = On_TDLS_Ch_Switch_Rsp(adapter, precv_frame, ptdls_sta);
1082 /* First byte of WFA OUI */
1084 if (_rtw_memcmp(WFA_OUI, paction, 3)) {
1085 /* Probe request frame */
1086 if (*(paction + 3) == 0x04) {
1087 /* WFDTDLS: for sigma test, do not setup direct link automatically */
1088 ptdlsinfo->dev_discovered = _TRUE;
1089 RTW_INFO("recv tunneled probe request frame\n");
1090 issue_tunneled_probe_rsp(adapter, precv_frame);
1092 /* Probe response frame */
1093 if (*(paction + 3) == 0x05) {
1094 /* WFDTDLS: for sigma test, do not setup direct link automatically */
1095 ptdlsinfo->dev_discovered = _TRUE;
1096 RTW_INFO("recv tunneled probe response frame\n");
1100 #endif /* CONFIG_WFD */
1102 RTW_INFO("receive TDLS frame %d but not support\n", *paction);
1111 #endif /* CONFIG_TDLS */
1113 void count_rx_stats(_adapter *padapter, union recv_frame *prframe, struct sta_info *sta)
1116 struct sta_info *psta = NULL;
1117 struct stainfo_stats *pstats = NULL;
1118 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
1119 struct recv_priv *precvpriv = &padapter->recvpriv;
1121 sz = get_recvframe_len(prframe);
1122 precvpriv->rx_bytes += sz;
1124 padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
1126 if ((!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst)))
1127 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
1132 psta = prframe->u.hdr.psta;
1135 u8 is_ra_bmc = IS_MCAST(pattrib->ra);
1137 pstats = &psta->sta_stats;
1139 pstats->last_rx_time = rtw_get_current_time();
1140 pstats->rx_data_pkts++;
1141 pstats->rx_bytes += sz;
1142 if (is_broadcast_mac_addr(pattrib->ra)) {
1143 pstats->rx_data_bc_pkts++;
1144 pstats->rx_bc_bytes += sz;
1145 } else if (is_ra_bmc) {
1146 pstats->rx_data_mc_pkts++;
1147 pstats->rx_mc_bytes += sz;
1151 pstats->rxratecnt[pattrib->data_rate]++;
1152 /*record rx packets for every tid*/
1153 pstats->rx_data_qos_pkts[pattrib->priority]++;
1155 #ifdef CONFIG_DYNAMIC_SOML
1156 rtw_dyn_soml_byte_update(padapter, pattrib->data_rate, sz);
1158 #if defined(CONFIG_CHECK_LEAVE_LPS) && defined(CONFIG_LPS_CHK_BY_TP)
1159 if (adapter_to_pwrctl(padapter)->lps_chk_by_tp)
1160 traffic_check_for_leave_lps_by_tp(padapter, _FALSE, psta);
1161 #endif /* CONFIG_LPS */
1165 #ifdef CONFIG_CHECK_LEAVE_LPS
1166 #ifdef CONFIG_LPS_CHK_BY_TP
1167 if (!adapter_to_pwrctl(padapter)->lps_chk_by_tp)
1169 traffic_check_for_leave_lps(padapter, _FALSE, 0);
1170 #endif /* CONFIG_CHECK_LEAVE_LPS */
1174 sint sta2sta_data_frame(
1176 union recv_frame *precv_frame,
1177 struct sta_info **psta
1180 u8 *ptr = precv_frame->u.hdr.rx_data;
1181 sint ret = _SUCCESS;
1182 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1183 struct sta_priv *pstapriv = &adapter->stapriv;
1184 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1185 u8 *mybssid = get_bssid(pmlmepriv);
1186 u8 *myhwaddr = adapter_mac_addr(adapter);
1187 u8 *sta_addr = pattrib->ta;
1188 sint bmcast = IS_MCAST(pattrib->dst);
1191 struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1192 #ifdef CONFIG_TDLS_CH_SW
1193 struct tdls_ch_switch *pchsw_info = &ptdlsinfo->chsw_info;
1195 struct sta_info *ptdls_sta = NULL;
1196 u8 *psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
1197 /* frame body located after [+2]: ether-type, [+1]: payload type */
1198 u8 *pframe_body = psnap_type + 2 + 1;
1202 /* RTW_INFO("[%s] %d, seqnum:%d\n", __FUNCTION__, __LINE__, pattrib->seq_num); */
1204 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1205 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE)) {
1207 /* filter packets that SA is myself or multicast or broadcast */
1208 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1213 if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1218 if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1219 _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1220 (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1225 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE) {
1228 /* direct link data transfer */
1229 if (ptdlsinfo->link_established == _TRUE) {
1230 *psta = ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->ta);
1231 if (ptdls_sta == NULL) {
1234 } else if (ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE) {
1235 /* filter packets that SA is myself or multicast or broadcast */
1236 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1240 /* da should be for me */
1241 if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1246 if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1247 _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1248 (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1253 #ifdef CONFIG_TDLS_CH_SW
1254 if (ATOMIC_READ(&pchsw_info->chsw_on) == _TRUE) {
1255 if (adapter->mlmeextpriv.cur_channel != rtw_get_oper_ch(adapter)) {
1256 pchsw_info->ch_sw_state |= TDLS_PEER_AT_OFF_STATE;
1257 if (!(pchsw_info->ch_sw_state & TDLS_CH_SW_INITIATOR_STATE))
1258 _cancel_timer_ex(&ptdls_sta->ch_sw_timer);
1259 /* On_TDLS_Peer_Traffic_Rsp(adapter, precv_frame); */
1264 /* process UAPSD tdls sta */
1265 process_pwrbit_data(adapter, precv_frame, ptdls_sta);
1267 /* if NULL-frame, check pwrbit */
1268 if ((get_frame_sub_type(ptr) & WIFI_DATA_NULL) == WIFI_DATA_NULL) {
1269 /* NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA */
1270 if (GetPwrMgt(ptr)) {
1271 /* it would be triggered when we are off channel and receiving NULL DATA */
1272 /* we can confirm that peer STA is at off channel */
1273 RTW_INFO("TDLS: recv peer null frame with pwr bit 1\n");
1274 /* ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE; */
1277 /* TODO: Updated BSSID's seq. */
1278 /* RTW_INFO("drop Null Data\n"); */
1279 ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
1284 /* receive some of all TDLS management frames, process it at ON_TDLS */
1285 if (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, 2)) {
1286 ret = OnTDLS(adapter, precv_frame);
1290 if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE)
1291 process_wmmps_data(adapter, precv_frame, ptdls_sta);
1293 ptdls_sta->tdls_sta_state &= ~(TDLS_WAIT_PTR_STATE);
1297 #endif /* CONFIG_TDLS */
1299 /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
1300 if (!_rtw_memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
1306 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1308 /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */
1309 if (!IS_MCAST(pattrib->bssid)) {
1313 } else { /* not mc-frame */
1314 /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
1315 if (!_rtw_memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
1321 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) {
1322 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1323 _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
1324 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1325 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1326 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1333 if (ptdls_sta == NULL)
1335 *psta = rtw_get_stainfo(pstapriv, sta_addr);
1337 if (*psta == NULL) {
1338 #ifdef CONFIG_MP_INCLUDED
1339 if (adapter->registrypriv.mp_mode == 1) {
1340 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1341 adapter->mppriv.rx_pktloss++;
1353 sint ap2sta_data_frame(
1355 union recv_frame *precv_frame,
1356 struct sta_info **psta)
1358 u8 *ptr = precv_frame->u.hdr.rx_data;
1359 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1360 sint ret = _SUCCESS;
1361 struct sta_priv *pstapriv = &adapter->stapriv;
1362 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1363 u8 *mybssid = get_bssid(pmlmepriv);
1364 u8 *myhwaddr = adapter_mac_addr(adapter);
1365 sint bmcast = IS_MCAST(pattrib->dst);
1368 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1369 && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE
1370 || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE)
1373 /* filter packets that SA is myself or multicast or broadcast */
1374 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
1375 #ifdef DBG_RX_DROP_FRAME
1376 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" SA="MAC_FMT", myhwaddr="MAC_FMT"\n"
1377 , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->src), MAC_ARG(myhwaddr));
1383 /* da should be for me */
1384 if ((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
1385 #ifdef DBG_RX_DROP_FRAME
1386 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DA="MAC_FMT"\n"
1387 , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->dst));
1395 if (_rtw_memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1396 _rtw_memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
1397 (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
1398 #ifdef DBG_RX_DROP_FRAME
1399 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" BSSID="MAC_FMT", mybssid="MAC_FMT"\n"
1400 , FUNC_ADPT_ARG(adapter), MAC_ARG(pattrib->bssid), MAC_ARG(mybssid));
1404 && !IS_RADAR_DETECTED(adapter_to_rfctl(adapter))
1406 RTW_INFO(ADPT_FMT" -issue_deauth to the nonassociated ap=" MAC_FMT " for the reason(7)\n", ADPT_ARG(adapter), MAC_ARG(pattrib->bssid));
1407 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1414 *psta = rtw_get_stainfo(pstapriv, pattrib->ta);
1415 if (*psta == NULL) {
1416 #ifdef DBG_RX_DROP_FRAME
1417 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under STATION_MODE ; drop pkt\n"
1418 , FUNC_ADPT_ARG(adapter));
1424 /*if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1428 if (get_frame_sub_type(ptr) & BIT(6)) {
1429 /* No data, will not indicate to upper layer, temporily count it here */
1430 count_rx_stats(adapter, precv_frame, *psta);
1431 ret = RTW_RX_HANDLED;
1435 } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1436 (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
1437 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1438 _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
1439 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1440 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1441 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1444 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1445 if (*psta == NULL) {
1446 #ifdef DBG_RX_DROP_FRAME
1447 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under WIFI_MP_STATE ; drop pkt\n"
1448 , FUNC_ADPT_ARG(adapter));
1455 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1457 ret = RTW_RX_HANDLED;
1460 if (_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
1461 *psta = rtw_get_stainfo(pstapriv, pattrib->ta);
1462 if (*psta == NULL) {
1464 /* for AP multicast issue , modify by yiwei */
1465 static systime send_issue_deauth_time = 0;
1467 /* RTW_INFO("After send deauth , %u ms has elapsed.\n", rtw_get_passing_time_ms(send_issue_deauth_time)); */
1469 if (rtw_get_passing_time_ms(send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) {
1470 send_issue_deauth_time = rtw_get_current_time();
1472 RTW_INFO("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1474 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1480 #ifdef DBG_RX_DROP_FRAME
1481 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" fw_state:0x%x\n"
1482 , FUNC_ADPT_ARG(adapter), get_fwstate(pmlmepriv));
1493 sint sta2ap_data_frame(
1495 union recv_frame *precv_frame,
1496 struct sta_info **psta)
1498 u8 *ptr = precv_frame->u.hdr.rx_data;
1499 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1500 struct sta_priv *pstapriv = &adapter->stapriv;
1501 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1502 unsigned char *mybssid = get_bssid(pmlmepriv);
1503 sint ret = _SUCCESS;
1506 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE) {
1507 /* For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
1508 if (!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
1513 *psta = rtw_get_stainfo(pstapriv, pattrib->ta);
1514 if (*psta == NULL) {
1515 if (!IS_RADAR_DETECTED(adapter_to_rfctl(adapter))) {
1516 RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1517 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1520 ret = RTW_RX_HANDLED;
1524 process_pwrbit_data(adapter, precv_frame, *psta);
1526 if ((get_frame_sub_type(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE)
1527 process_wmmps_data(adapter, precv_frame, *psta);
1529 if (get_frame_sub_type(ptr) & BIT(6)) {
1530 /* No data, will not indicate to upper layer, temporily count it here */
1531 count_rx_stats(adapter, precv_frame, *psta);
1532 ret = RTW_RX_HANDLED;
1535 } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1536 (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) {
1537 /* RTW_INFO("%s ,in WIFI_MP_STATE\n",__func__); */
1538 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
1539 _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
1540 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
1541 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
1542 _rtw_memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
1545 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */
1546 if (*psta == NULL) {
1547 #ifdef DBG_RX_DROP_FRAME
1548 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" can't get psta under WIFI_MP_STATE ; drop pkt\n"
1549 , FUNC_ADPT_ARG(adapter));
1556 u8 *myhwaddr = adapter_mac_addr(adapter);
1557 if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1558 ret = RTW_RX_HANDLED;
1561 RTW_INFO("issue_deauth to sta=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src));
1562 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1563 ret = RTW_RX_HANDLED;
1574 sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame);
1575 sint validate_recv_ctrl_frame(_adapter *padapter, union recv_frame *precv_frame)
1577 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1578 struct sta_priv *pstapriv = &padapter->stapriv;
1579 u8 *pframe = precv_frame->u.hdr.rx_data;
1580 struct sta_info *psta = NULL;
1581 /* uint len = precv_frame->u.hdr.len; */
1583 /* RTW_INFO("+validate_recv_ctrl_frame\n"); */
1585 if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1588 /* receive the frames that ra(a1) is my address */
1589 if (!_rtw_memcmp(GetAddr1Ptr(pframe), adapter_mac_addr(padapter), ETH_ALEN))
1592 psta = rtw_get_stainfo(pstapriv, get_addr2_ptr(pframe));
1596 /* for rx pkt statistics */
1597 psta->sta_stats.last_rx_time = rtw_get_current_time();
1598 psta->sta_stats.rx_ctrl_pkts++;
1600 /* only handle ps-poll */
1601 if (get_frame_sub_type(pframe) == WIFI_PSPOLL) {
1602 #ifdef CONFIG_AP_MODE
1606 aid = GetAid(pframe);
1607 if (psta->cmn.aid != aid)
1610 switch (pattrib->priority) {
1613 wmmps_ac = psta->uapsd_bk & BIT(0);
1617 wmmps_ac = psta->uapsd_vi & BIT(0);
1621 wmmps_ac = psta->uapsd_vo & BIT(0);
1626 wmmps_ac = psta->uapsd_be & BIT(0);
1633 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1634 RTW_INFO("%s alive check-rx ps-poll\n", __func__);
1635 psta->expire_to = pstapriv->expire_to;
1636 psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1639 if ((psta->state & WIFI_SLEEP_STATE) && (rtw_tim_map_is_set(padapter, pstapriv->sta_dz_bitmap, psta->cmn.aid))) {
1641 _list *xmitframe_plist, *xmitframe_phead;
1642 struct xmit_frame *pxmitframe = NULL;
1643 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1645 /* _enter_critical_bh(&psta->sleep_q.lock, &irqL); */
1646 _enter_critical_bh(&pxmitpriv->lock, &irqL);
1648 xmitframe_phead = get_list_head(&psta->sleep_q);
1649 xmitframe_plist = get_next(xmitframe_phead);
1651 if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE) {
1652 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1654 xmitframe_plist = get_next(xmitframe_plist);
1656 rtw_list_delete(&pxmitframe->list);
1660 if (psta->sleepq_len > 0)
1661 pxmitframe->attrib.mdata = 1;
1663 pxmitframe->attrib.mdata = 0;
1665 pxmitframe->attrib.triggered = 1;
1667 /* RTW_INFO("handling ps-poll, q_len=%d\n", psta->sleepq_len); */
1668 /* RTW_INFO_DUMP("handling, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
1671 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
1672 if (rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
1673 rtw_os_xmit_complete(padapter, pxmitframe);
1674 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
1676 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1678 if (psta->sleepq_len == 0) {
1679 rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
1681 /* RTW_INFO("after handling ps-poll\n"); */
1682 /* RTW_INFO_DUMP("after handling, tim=", pstapriv->tim_bitmap, pstapriv->aid_bmp_len); */
1684 /* upate BCN for TIM IE */
1685 /* update_BCNTIM(padapter); */
1686 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
1689 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
1690 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1693 /* _exit_critical_bh(&psta->sleep_q.lock, &irqL); */
1694 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1696 /* RTW_INFO("no buffered packets to xmit\n"); */
1697 if (rtw_tim_map_is_set(padapter, pstapriv->tim_bitmap, psta->cmn.aid)) {
1698 if (psta->sleepq_len == 0) {
1699 RTW_INFO("no buffered packets to xmit\n");
1701 /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1702 issue_nulldata(padapter, psta->cmn.mac_addr, 0, 0, 0);
1704 RTW_INFO("error!psta->sleepq_len=%d\n", psta->sleepq_len);
1705 psta->sleepq_len = 0;
1708 rtw_tim_map_clear(padapter, pstapriv->tim_bitmap, psta->cmn.aid);
1710 /* upate BCN for TIM IE */
1711 /* update_BCNTIM(padapter); */
1712 update_beacon(padapter, _TIM_IE_, NULL, _TRUE);
1716 #endif /* CONFIG_AP_MODE */
1717 } else if (get_frame_sub_type(pframe) == WIFI_NDPA) {
1718 #ifdef CONFIG_BEAMFORMING
1719 rtw_beamforming_get_ndpa_frame(padapter, precv_frame);
1720 #endif/*CONFIG_BEAMFORMING*/
1721 } else if (get_frame_sub_type(pframe) == WIFI_BAR) {
1722 rtw_process_bar_frame(padapter, precv_frame);
1729 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
1730 static sint validate_mgmt_protect(_adapter *adapter, union recv_frame *precv_frame)
1732 #define DBG_VALIDATE_MGMT_PROTECT 0
1733 #define DBG_VALIDATE_MGMT_DEC 0
1735 struct security_priv *sec = &adapter->securitypriv;
1736 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
1737 struct sta_info *psta = precv_frame->u.hdr.psta;
1744 #ifdef CONFIG_IEEE80211W
1755 #ifdef CONFIG_RTW_MESH
1756 if (MLME_IS_MESH(adapter)) {
1757 if (!adapter->mesh_info.mesh_auth_id)
1758 return pattrib->privacy ? _FAIL : _SUCCESS;
1761 if (SEC_IS_BIP_KEY_INSTALLED(sec) == _FALSE)
1764 ptr = precv_frame->u.hdr.rx_data;
1765 type = GetFrameType(ptr);
1766 subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
1767 is_bmc = IS_MCAST(GetAddr1Ptr(ptr));
1769 #if DBG_VALIDATE_MGMT_PROTECT
1770 if (subtype == WIFI_DEAUTH) {
1771 RTW_INFO(FUNC_ADPT_FMT" bmc:%u, deauth, privacy:%u, encrypt:%u, bdecrypted:%u\n"
1772 , FUNC_ADPT_ARG(adapter)
1773 , is_bmc, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1774 } else if (subtype == WIFI_DISASSOC) {
1775 RTW_INFO(FUNC_ADPT_FMT" bmc:%u, disassoc, privacy:%u, encrypt:%u, bdecrypted:%u\n"
1776 , FUNC_ADPT_ARG(adapter)
1777 , is_bmc, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1778 } if (subtype == WIFI_ACTION) {
1779 if (pattrib->privacy) {
1780 RTW_INFO(FUNC_ADPT_FMT" bmc:%u, action(?), privacy:%u, encrypt:%u, bdecrypted:%u\n"
1781 , FUNC_ADPT_ARG(adapter)
1782 , is_bmc, pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1784 RTW_INFO(FUNC_ADPT_FMT" bmc:%u, action(%u), privacy:%u, encrypt:%u, bdecrypted:%u\n"
1785 , FUNC_ADPT_ARG(adapter), is_bmc
1786 , *(ptr + sizeof(struct rtw_ieee80211_hdr_3addr))
1787 , pattrib->privacy, pattrib->encrypt, pattrib->bdecrypted);
1792 if (!pattrib->privacy) {
1793 if (!psta || !(psta->flags & WLAN_STA_MFP)) {
1794 /* peer is not MFP capable, no need to check */
1798 if (subtype == WIFI_ACTION)
1799 category = *(ptr + sizeof(struct rtw_ieee80211_hdr_3addr));
1802 /* broadcast cases */
1803 if (subtype == WIFI_ACTION) {
1804 if (CATEGORY_IS_GROUP_PRIVACY(category)) {
1805 /* drop broadcast group privacy action frame without encryption */
1806 #if DBG_VALIDATE_MGMT_PROTECT
1807 RTW_INFO(FUNC_ADPT_FMT" broadcast gp action(%u) w/o encrypt\n"
1808 , FUNC_ADPT_ARG(adapter), category);
1812 if (CATEGORY_IS_ROBUST(category)) {
1813 /* broadcast robust action frame need BIP check */
1817 if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
1818 /* broadcast deauth or disassoc frame need BIP check */
1825 #ifdef CONFIG_IEEE80211W
1826 if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) {
1827 if (!MLME_IS_MESH(adapter)) {
1828 unsigned short reason = le16_to_cpu(*(unsigned short *)(ptr + WLAN_HDR_A3_LEN));
1830 #if DBG_VALIDATE_MGMT_PROTECT
1831 RTW_INFO(FUNC_ADPT_FMT" unicast %s, reason=%d w/o encrypt\n"
1832 , FUNC_ADPT_ARG(adapter), subtype == WIFI_DEAUTH ? "deauth" : "disassoc", reason);
1834 if (reason == 6 || reason == 7) {
1835 /* issue sa query request */
1836 issue_action_SA_Query(adapter, psta->cmn.mac_addr, 0, 0, IEEE80211W_RIGHT_KEY);
1843 if (subtype == WIFI_ACTION && CATEGORY_IS_ROBUST(category)) {
1844 if (psta->bpairwise_key_installed == _TRUE) {
1845 #if DBG_VALIDATE_MGMT_PROTECT
1846 RTW_INFO(FUNC_ADPT_FMT" unicast robust action(%d) w/o encrypt\n"
1847 , FUNC_ADPT_ARG(adapter), category);
1856 #ifdef CONFIG_IEEE80211W
1857 #ifdef CONFIG_RTW_MESH
1858 if (MLME_IS_MESH(adapter)) {
1859 if (psta->igtk_bmp) {
1860 igtk = psta->igtk.skey;
1861 igtk_id = psta->igtk_id;
1862 ipn = &psta->igtk_pn.val;
1864 /* mesh MFP without IGTK */
1870 igtk = sec->dot11wBIPKey[sec->dot11wBIPKeyid].skey;
1871 igtk_id = sec->dot11wBIPKeyid;
1872 ipn = &sec->dot11wBIPrxpn.val;
1875 /* verify BIP MME IE */
1876 ret = rtw_BIP_verify(adapter
1877 , get_recvframe_data(precv_frame)
1878 , get_recvframe_len(precv_frame)
1879 , igtk, igtk_id, ipn);
1881 /* RTW_INFO("802.11w BIP verify fail\n"); */
1884 } else if (ret == RTW_RX_HANDLED) {
1885 #if DBG_VALIDATE_MGMT_PROTECT
1886 RTW_INFO(FUNC_ADPT_FMT" none protected packet\n", FUNC_ADPT_ARG(adapter));
1890 #endif /* CONFIG_IEEE80211W */
1894 /* cases to decrypt mgmt frame */
1895 pattrib->bdecrypted = 0;
1896 pattrib->encrypt = _AES_;
1897 pattrib->hdrlen = sizeof(struct rtw_ieee80211_hdr_3addr);
1899 /* set iv and icv length */
1900 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1901 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1902 _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
1904 /* actual management data frame body */
1905 data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len;
1906 mgmt_DATA = rtw_zmalloc(data_len);
1907 if (mgmt_DATA == NULL) {
1908 RTW_INFO(FUNC_ADPT_FMT" mgmt allocate fail !!!!!!!!!\n", FUNC_ADPT_ARG(adapter));
1912 #if DBG_VALIDATE_MGMT_DEC
1913 /* dump the packet content before decrypt */
1917 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
1918 for (pp = 0; pp < pattrib->pkt_len; pp++)
1919 printk(" %02x ", ptr[pp]);
1924 precv_frame = decryptor(adapter, precv_frame);
1925 /* save actual management data frame body */
1926 _rtw_memcpy(mgmt_DATA, ptr + pattrib->hdrlen + pattrib->iv_len, data_len);
1927 /* overwrite the iv field */
1928 _rtw_memcpy(ptr + pattrib->hdrlen, mgmt_DATA, data_len);
1929 /* remove the iv and icv length */
1930 pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len;
1931 rtw_mfree(mgmt_DATA, data_len);
1933 #if DBG_VALIDATE_MGMT_DEC
1934 /* print packet content after decryption */
1938 printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len);
1939 for (pp = 0; pp < pattrib->pkt_len; pp++)
1940 printk(" %02x ", ptr[pp]);
1946 #if DBG_VALIDATE_MGMT_PROTECT
1947 RTW_INFO(FUNC_ADPT_FMT" mgmt descrypt fail !!!!!!!!!\n", FUNC_ADPT_ARG(adapter));
1959 #endif /* defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH) */
1961 union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame);
1963 sint validate_recv_mgnt_frame(PADAPTER padapter, union recv_frame *precv_frame)
1965 struct sta_info *psta = precv_frame->u.hdr.psta
1966 = rtw_get_stainfo(&padapter->stapriv, get_addr2_ptr(precv_frame->u.hdr.rx_data));
1968 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
1969 if (validate_mgmt_protect(padapter, precv_frame) == _FAIL) {
1970 DBG_COUNTER(padapter->rx_logs.core_rx_pre_mgmt_err_80211w);
1975 precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1976 if (precv_frame == NULL)
1979 /* for rx pkt statistics */
1981 psta->sta_stats.last_rx_time = rtw_get_current_time();
1982 psta->sta_stats.rx_mgnt_pkts++;
1983 if (get_frame_sub_type(precv_frame->u.hdr.rx_data) == WIFI_BEACON)
1984 psta->sta_stats.rx_beacon_pkts++;
1985 else if (get_frame_sub_type(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ)
1986 psta->sta_stats.rx_probereq_pkts++;
1987 else if (get_frame_sub_type(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) {
1988 if (_rtw_memcmp(adapter_mac_addr(padapter), GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN) == _TRUE)
1989 psta->sta_stats.rx_probersp_pkts++;
1990 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))
1991 || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)))
1992 psta->sta_stats.rx_probersp_bm_pkts++;
1994 psta->sta_stats.rx_probersp_uo_pkts++;
1998 #ifdef CONFIG_INTEL_PROXIM
1999 if (padapter->proximity.proxim_on == _TRUE) {
2000 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2001 struct recv_stat *prxstat = (struct recv_stat *) precv_frame->u.hdr.rx_head ;
2002 u8 *pda, *psa, *pbssid, *ptr;
2003 ptr = precv_frame->u.hdr.rx_data;
2006 pbssid = get_hdr_bssid(ptr);
2009 _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
2010 _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
2012 _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
2014 switch (pattrib->to_fr_ds) {
2016 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
2017 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
2021 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
2022 _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
2026 _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
2027 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
2031 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2032 _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2039 pattrib->priority = 0;
2040 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24;
2042 padapter->proximity.proxim_rx(padapter, precv_frame);
2045 mgt_dispatcher(padapter, precv_frame);
2047 #if defined(CONFIG_IEEE80211W) || defined(CONFIG_RTW_MESH)
2054 sint validate_recv_data_frame(_adapter *adapter, union recv_frame *precv_frame)
2056 u8 bretry, a4_shift;
2057 struct sta_info *psta = NULL;
2058 u8 *ptr = precv_frame->u.hdr.rx_data;
2059 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2060 struct security_priv *psecuritypriv = &adapter->securitypriv;
2061 sint ret = _SUCCESS;
2063 bretry = GetRetry(ptr);
2064 a4_shift = (pattrib->to_fr_ds == 3) ? ETH_ALEN : 0;
2066 /* some address fields are different when using AMSDU */
2068 pattrib->amsdu = GetAMsdu(ptr + WLAN_HDR_A3_LEN + a4_shift);
2072 #ifdef CONFIG_RTW_MESH
2073 if (MLME_IS_MESH(adapter)) {
2074 ret = rtw_mesh_rx_data_validate_hdr(adapter, precv_frame, &psta);
2075 goto pre_validate_status_chk;
2079 switch (pattrib->to_fr_ds) {
2081 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2082 _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2083 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
2084 _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
2085 _rtw_memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
2086 ret = sta2sta_data_frame(adapter, precv_frame, &psta);
2090 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2091 _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2092 _rtw_memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
2093 _rtw_memcpy(pattrib->src, GetAddr3Ptr(ptr), ETH_ALEN);
2094 _rtw_memcpy(pattrib->bssid, get_addr2_ptr(ptr), ETH_ALEN);
2095 ret = ap2sta_data_frame(adapter, precv_frame, &psta);
2099 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
2100 _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
2101 _rtw_memcpy(pattrib->dst, GetAddr3Ptr(ptr), ETH_ALEN);
2102 _rtw_memcpy(pattrib->src, get_addr2_ptr(ptr), ETH_ALEN);
2103 _rtw_memcpy(pattrib->bssid, GetAddr1Ptr(ptr), ETH_ALEN);
2104 ret = sta2ap_data_frame(adapter, precv_frame, &psta);
2109 /* WDS is not supported */
2114 #ifdef CONFIG_RTW_MESH
2115 pre_validate_status_chk:
2118 #ifdef DBG_RX_DROP_FRAME
2119 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" case:%d, res:%d, ra="MAC_FMT", ta="MAC_FMT"\n"
2120 , FUNC_ADPT_ARG(adapter), pattrib->to_fr_ds, ret, MAC_ARG(GetAddr1Ptr(ptr)), MAC_ARG(get_addr2_ptr(ptr)));
2123 } else if (ret == RTW_RX_HANDLED)
2128 #ifdef DBG_RX_DROP_FRAME
2129 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" psta == NULL, ra="MAC_FMT", ta="MAC_FMT"\n"
2130 , FUNC_ADPT_ARG(adapter), MAC_ARG(GetAddr1Ptr(ptr)), MAC_ARG(get_addr2_ptr(ptr)));
2136 precv_frame->u.hdr.psta = psta;
2137 precv_frame->u.hdr.preorder_ctrl = NULL;
2138 pattrib->ack_policy = 0;
2140 /* parsing QC field */
2141 if (pattrib->qos == 1) {
2142 pattrib->priority = GetPriority((ptr + WLAN_HDR_A3_LEN + a4_shift)); /* point to Qos field*/
2143 pattrib->ack_policy = GetAckpolicy((ptr + WLAN_HDR_A3_LEN + a4_shift));
2144 pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN + a4_shift;
2145 if (pattrib->priority != 0 && pattrib->priority != 3)
2146 adapter->recvpriv.is_any_non_be_pkts = _TRUE;
2148 adapter->recvpriv.is_any_non_be_pkts = _FALSE;
2150 pattrib->priority = 0;
2151 pattrib->hdrlen = WLAN_HDR_A3_LEN + a4_shift;
2154 if (pattrib->order) /* HT-CTRL 11n */
2155 pattrib->hdrlen += 4;
2157 /* decache, drop duplicate recv packets */
2158 ret = recv_decache(precv_frame);
2162 if (!IS_MCAST(pattrib->ra)) {
2165 precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
2167 if (recv_ucast_pn_decache(precv_frame) == _FAIL) {
2168 #ifdef DBG_RX_DROP_FRAME
2169 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv_ucast_pn_decache return _FAIL for sta="MAC_FMT"\n"
2170 , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr));
2176 if (recv_bcast_pn_decache(precv_frame) == _FAIL) {
2177 #ifdef DBG_RX_DROP_FRAME
2178 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recv_bcast_pn_decache return _FAIL for sta="MAC_FMT"\n"
2179 , FUNC_ADPT_ARG(adapter), MAC_ARG(psta->cmn.mac_addr));
2186 if (pattrib->privacy) {
2188 if ((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy == _AES_))
2189 pattrib->encrypt = psta->dot118021XPrivacy;
2191 #endif /* CONFIG_TDLS */
2192 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
2195 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
2197 pattrib->encrypt = 0;
2198 pattrib->iv_len = pattrib->icv_len = 0;
2201 #ifdef CONFIG_RTW_MESH
2203 && pattrib->mesh_ctrl_present
2204 && (!pattrib->encrypt || pattrib->bdecrypted))
2205 ret = rtw_mesh_rx_validate_mctrl_non_amsdu(adapter, precv_frame);
2212 static inline void dump_rx_packet(u8 *ptr)
2216 RTW_INFO("#############################\n");
2217 for (i = 0; i < 64; i = i + 8)
2218 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
2219 *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
2220 RTW_INFO("#############################\n");
2223 sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame);
2224 sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
2226 /* shall check frame subtype, to / from ds, da, bssid */
2228 /* then call check if rx seq/frag. duplicated. */
2232 sint retval = _SUCCESS;
2234 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
2235 struct recv_priv *precvpriv = &adapter->recvpriv;
2237 u8 *ptr = precv_frame->u.hdr.rx_data;
2238 u8 ver = (unsigned char)(*ptr) & 0x3 ;
2239 #ifdef CONFIG_FIND_BEST_CHANNEL
2240 struct rf_ctl_t *rfctl = adapter_to_rfctl(adapter);
2241 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
2245 struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
2246 #endif /* CONFIG_TDLS */
2247 #ifdef CONFIG_WAPI_SUPPORT
2248 PRT_WAPI_T pWapiInfo = &adapter->wapiInfo;
2249 struct recv_frame_hdr *phdr = &precv_frame->u.hdr;
2252 u8 external_len = 0;
2256 #ifdef CONFIG_FIND_BEST_CHANNEL
2257 if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
2258 int ch_set_idx = rtw_chset_search_ch(rfctl->channel_set, rtw_get_oper_ch(adapter));
2259 if (ch_set_idx >= 0)
2260 rfctl->channel_set[ch_set_idx].rx_count++;
2265 if (ptdlsinfo->ch_sensing == 1 && ptdlsinfo->cur_channel != 0)
2266 ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel - 1]++;
2267 #endif /* CONFIG_TDLS */
2269 #ifdef RTK_DMP_PLATFORM
2274 for (i = 0; i < 64; i = i + 8)
2275 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr + i),
2276 *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
2281 #endif /* RTK_DMP_PLATFORM */
2283 /* add version chk */
2286 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err);
2290 type = GetFrameType(ptr);
2291 subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
2293 pattrib->to_fr_ds = get_tofr_ds(ptr);
2295 pattrib->frag_num = GetFragNum(ptr);
2296 pattrib->seq_num = GetSequence(ptr);
2298 pattrib->pw_save = GetPwrMgt(ptr);
2299 pattrib->mfrag = GetMFrag(ptr);
2300 pattrib->mdata = GetMData(ptr);
2301 pattrib->privacy = GetPrivacy(ptr);
2302 pattrib->order = GetOrder(ptr);
2303 #ifdef CONFIG_WAPI_SUPPORT
2304 sc = (pattrib->seq_num << 4) | pattrib->frag_num;
2307 #if 1 /* Dump rx packets */
2311 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
2312 if (bDumpRxPkt == 1) /* dump all rx packets */
2313 dump_rx_packet(ptr);
2314 else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE))
2315 dump_rx_packet(ptr);
2316 else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE))
2317 dump_rx_packet(ptr);
2321 case WIFI_MGT_TYPE: /* mgnt */
2322 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt);
2323 retval = validate_recv_mgnt_frame(adapter, precv_frame);
2324 if (retval == _FAIL) {
2325 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err);
2327 retval = _FAIL; /* only data frame return _SUCCESS */
2329 case WIFI_CTRL_TYPE: /* ctrl */
2330 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl);
2331 retval = validate_recv_ctrl_frame(adapter, precv_frame);
2332 if (retval == _FAIL) {
2333 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err);
2335 retval = _FAIL; /* only data frame return _SUCCESS */
2337 case WIFI_DATA_TYPE: /* data */
2338 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data);
2339 #ifdef CONFIG_WAPI_SUPPORT
2345 wai_pkt = rtw_wapi_is_wai_packet(adapter, ptr);
2347 phdr->bIsWaiPacket = wai_pkt;
2350 if (sc != adapter->wapiInfo.wapiSeqnumAndFragNum)
2351 adapter->wapiInfo.wapiSeqnumAndFragNum = sc;
2354 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_seq_err);
2359 if (rtw_wapi_drop_for_key_absent(adapter, get_addr2_ptr(ptr))) {
2361 WAPI_TRACE(WAPI_RX, "drop for key absent for rx\n");
2362 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_wapi_key_err);
2369 pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
2370 retval = validate_recv_data_frame(adapter, precv_frame);
2371 if (retval == _FAIL) {
2372 precvpriv->dbg_rx_drop_count++;
2373 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err);
2374 } else if (retval == _SUCCESS) {
2375 #ifdef DBG_RX_DUMP_EAP
2376 if (!pattrib->encrypt || pattrib->bdecrypted) {
2381 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
2382 /* get ether_type */
2383 _rtw_memcpy(ð_type, ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + LLC_HEADER_SIZE, 2);
2384 eth_type = ntohs((unsigned short) eth_type);
2385 if ((bDumpRxPkt == 4) && (eth_type == 0x888e))
2386 dump_rx_packet(ptr);
2390 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled);
2393 DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown);
2394 #ifdef DBG_RX_DROP_FRAME
2395 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" fail! type=0x%x\n"
2396 , FUNC_ADPT_ARG(adapter), type);
2409 /* remove the wlanhdr and add the eth_hdr */
2411 sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
2417 struct ieee80211_snap_hdr *psnap;
2419 sint ret = _SUCCESS;
2420 _adapter *adapter = precvframe->u.hdr.adapter;
2421 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2423 u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
2424 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
2427 if (pattrib->encrypt)
2428 recvframe_pull_tail(precvframe, pattrib->icv_len);
2430 psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib));
2431 psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + SNAP_SIZE;
2432 /* convert hdr + possible LLC headers into Ethernet header */
2433 /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
2434 if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
2435 (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) &&
2436 (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) ||
2437 /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
2438 _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
2439 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2442 /* Leave Ethernet header part of hdr and full payload */
2446 rmv_len = pattrib->hdrlen + pattrib->iv_len + RATTRIB_GET_MCTRL_LEN(pattrib) + (bsnaphdr ? SNAP_SIZE : 0);
2447 len = precvframe->u.hdr.len - rmv_len;
2450 _rtw_memcpy(ð_type, ptr + rmv_len, 2);
2451 eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
2452 pattrib->eth_type = eth_type;
2455 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)) {
2461 /* append rx status for mp test packets */
2462 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
2467 _rtw_memcpy(ptr, get_rxmem(precvframe), 24);
2470 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
2478 _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2479 _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
2483 _rtw_memcpy(ptr + 12, &len, 2);
2486 rtw_rframe_set_os_pkt(precvframe);
2495 static u8 SNAP_ETH_TYPE_APPLETALK_DDP[2] = {0x80, 0x9b};
2496 /* Datagram Delivery Protocol */
2497 static u8 SNAP_HDR_APPLETALK_DDP[3] = {0x08, 0x00, 0x07};
2498 static u8 oui_8021h[] = {0x00, 0x00, 0xf8};
2499 static u8 oui_rfc1042[] = {0x00, 0x00, 0x00};
2501 sint wlanhdr_to_ethhdr(union recv_frame *precvframe)
2507 struct ieee80211_snap_hdr *psnap;
2509 sint ret = _SUCCESS;
2510 _adapter *adapter = precvframe->u.hdr.adapter;
2511 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2513 u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
2514 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
2515 struct _vlan *pvlan = NULL;
2518 psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
2519 psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
2520 if (psnap->dsap == 0xaa && psnap->ssap == 0xaa && psnap->ctrl == 0x03) {
2521 if (_rtw_memcmp(psnap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN))
2522 bsnaphdr = _TRUE; /* wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042; */
2523 else if (_rtw_memcmp(psnap->oui, SNAP_HDR_APPLETALK_DDP, WLAN_IEEE_OUI_LEN) &&
2524 _rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_DDP, 2))
2525 bsnaphdr = _TRUE; /* wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK; */
2526 else if (_rtw_memcmp(psnap->oui, oui_8021h, WLAN_IEEE_OUI_LEN))
2527 bsnaphdr = _TRUE; /* wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL; */
2534 bsnaphdr = _FALSE; /* wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS; */
2536 rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
2538 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) {
2543 /* back to original pointer */
2549 _rtw_memcpy(ð_type, ptr, 2);
2550 eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
2553 if (pattrib->encrypt)
2554 recvframe_pull_tail(precvframe, pattrib->icv_len);
2556 if (eth_type == 0x8100) { /* vlan */
2557 pvlan = (struct _vlan *) ptr;
2559 /* eth_type = get_vlan_encap_proto(pvlan); */
2560 /* eth_type = pvlan->h_vlan_encapsulated_proto; */ /* ? */
2565 if (eth_type == 0x0800) { /* ip */
2566 /* struct iphdr* piphdr = (struct iphdr*) ptr; */
2567 /* __u8 tos = (unsigned char)(pattrib->priority & 0xff); */
2569 /* piphdr->tos = tos; */
2571 } else if (eth_type == 0x8712) { /* append rx status for mp test packets */
2573 /* _rtw_memcpy(ptr, get_rxmem(precvframe), 16); */
2575 #ifdef PLATFORM_OS_XP
2576 NDIS_PACKET_8021Q_INFO VlanPriInfo;
2577 UINT32 UserPriority = precvframe->u.hdr.attrib.priority;
2578 UINT32 VlanID = (pvlan != NULL ? get_vlan_id(pvlan) : 0);
2580 VlanPriInfo.Value = /* Get current value. */
2581 NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo);
2583 VlanPriInfo.TagHeader.UserPriority = UserPriority;
2584 VlanPriInfo.TagHeader.VlanId = VlanID ;
2586 VlanPriInfo.TagHeader.CanonicalFormatId = 0; /* Should be zero. */
2587 VlanPriInfo.TagHeader.Reserved = 0; /* Should be zero. */
2588 NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo) = VlanPriInfo.Value;
2592 if (eth_type == 0x8712) { /* append rx status for mp test packets */
2593 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
2594 _rtw_memcpy(ptr, get_rxmem(precvframe), 24);
2597 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2));
2599 _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2600 _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
2602 eth_type = htons((unsigned short)eth_type) ;
2603 _rtw_memcpy(ptr + 12, ð_type, 2);
2613 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2614 #ifdef PLATFORM_LINUX
2615 static void recvframe_expand_pkt(
2617 union recv_frame *prframe)
2619 struct recv_frame_hdr *pfhdr;
2626 pfhdr = &prframe->u.hdr;
2628 /* 6 is for IP header 8 bytes alignment in QoS packet case. */
2629 if (pfhdr->attrib.qos)
2634 /* for first fragment packet, need to allocate */
2635 /* (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet */
2636 /* 8 is for skb->data 8 bytes alignment.
2637 * alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128); */
2638 alloc_sz = 1664; /* round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment */
2640 /* 3 1. alloc new skb */
2641 /* prepare extra space for 4 bytes alignment */
2642 ppkt = rtw_skb_alloc(alloc_sz);
2645 return; /* no way to expand */
2647 /* 3 2. Prepare new skb to replace & release old skb */
2648 /* force ppkt->data at 8-byte alignment address */
2649 skb_reserve(ppkt, 8 - ((SIZE_PTR)ppkt->data & 7));
2650 /* force ip_hdr at 8-byte alignment address according to shift_sz */
2651 skb_reserve(ppkt, shift_sz);
2653 /* copy data to new pkt */
2654 ptr = skb_put(ppkt, pfhdr->len);
2656 _rtw_memcpy(ptr, pfhdr->rx_data, pfhdr->len);
2658 rtw_skb_free(pfhdr->pkt);
2660 /* attach new pkt to recvframe */
2662 pfhdr->rx_head = ppkt->head;
2663 pfhdr->rx_data = ppkt->data;
2664 pfhdr->rx_tail = skb_tail_pointer(ppkt);
2665 pfhdr->rx_end = skb_end_pointer(ppkt);
2668 #warning "recvframe_expand_pkt not implement, defrag may crash system"
2672 /* perform defrag */
2673 union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q);
2674 union recv_frame *recvframe_defrag(_adapter *adapter, _queue *defrag_q)
2676 _list *plist, *phead;
2677 u8 *data, wlanhdr_offset;
2679 struct recv_frame_hdr *pfhdr, *pnfhdr;
2680 union recv_frame *prframe, *pnextrframe;
2681 _queue *pfree_recv_queue;
2685 pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
2687 phead = get_list_head(defrag_q);
2688 plist = get_next(phead);
2689 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
2690 pfhdr = &prframe->u.hdr;
2691 rtw_list_delete(&(prframe->u.list));
2693 if (curfragnum != pfhdr->attrib.frag_num) {
2694 /* the first fragment number must be 0 */
2695 /* free the whole queue */
2696 rtw_free_recvframe(prframe, pfree_recv_queue);
2697 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2702 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2703 #ifndef CONFIG_SDIO_RX_COPY
2704 recvframe_expand_pkt(adapter, prframe);
2710 plist = get_list_head(defrag_q);
2712 plist = get_next(plist);
2714 data = get_recvframe_data(prframe);
2716 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
2717 pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u);
2718 pnfhdr = &pnextrframe->u.hdr;
2721 /* check the fragment sequence (2nd ~n fragment frame) */
2723 if (curfragnum != pnfhdr->attrib.frag_num) {
2724 /* the fragment number must be increasing (after decache) */
2725 /* release the defrag_q & prframe */
2726 rtw_free_recvframe(prframe, pfree_recv_queue);
2727 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2733 /* copy the 2nd~n fragment frame's payload to the first fragment */
2734 /* get the 2nd~last fragment frame's payload */
2736 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
2738 recvframe_pull(pnextrframe, wlanhdr_offset);
2740 /* append to first fragment frame's tail (if privacy frame, pull the ICV) */
2741 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
2744 _rtw_memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
2746 recvframe_put(prframe, pnfhdr->len);
2748 pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
2749 plist = get_next(plist);
2753 /* free the defrag_q queue and return the prframe */
2754 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2761 /* check if need to defrag, if needed queue the frame to defrag_q */
2762 union recv_frame *recvframe_chk_defrag(PADAPTER padapter, union recv_frame *precv_frame)
2767 struct recv_frame_hdr *pfhdr;
2768 struct sta_info *psta;
2769 struct sta_priv *pstapriv;
2771 union recv_frame *prtnframe = NULL;
2772 _queue *pfree_recv_queue, *pdefrag_q = NULL;
2775 pstapriv = &padapter->stapriv;
2777 pfhdr = &precv_frame->u.hdr;
2779 pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2781 /* need to define struct of wlan header frame ctrl */
2782 ismfrag = pfhdr->attrib.mfrag;
2783 fragnum = pfhdr->attrib.frag_num;
2785 psta_addr = pfhdr->attrib.ta;
2786 psta = rtw_get_stainfo(pstapriv, psta_addr);
2788 u8 type = GetFrameType(pfhdr->rx_data);
2789 if (type != WIFI_DATA_TYPE) {
2790 psta = rtw_get_bcmc_stainfo(padapter);
2792 pdefrag_q = &psta->sta_recvpriv.defrag_q;
2796 pdefrag_q = &psta->sta_recvpriv.defrag_q;
2798 if ((ismfrag == 0) && (fragnum == 0)) {
2799 prtnframe = precv_frame;/* isn't a fragment frame */
2803 /* 0~(n-1) fragment frame */
2804 /* enqueue to defraf_g */
2805 if (pdefrag_q != NULL) {
2807 /* the first fragment */
2808 if (_rtw_queue_empty(pdefrag_q) == _FALSE) {
2809 /* free current defrag_q */
2810 rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
2815 /* Then enqueue the 0~(n-1) fragment into the defrag_q */
2817 /* _rtw_spinlock(&pdefrag_q->lock); */
2818 phead = get_list_head(pdefrag_q);
2819 rtw_list_insert_tail(&pfhdr->list, phead);
2820 /* _rtw_spinunlock(&pdefrag_q->lock); */
2826 /* can't find this ta's defrag_queue, so free this recv_frame */
2827 rtw_free_recvframe(precv_frame, pfree_recv_queue);
2833 if ((ismfrag == 0) && (fragnum != 0)) {
2834 /* the last fragment frame */
2835 /* enqueue the last fragment */
2836 if (pdefrag_q != NULL) {
2837 /* _rtw_spinlock(&pdefrag_q->lock); */
2838 phead = get_list_head(pdefrag_q);
2839 rtw_list_insert_tail(&pfhdr->list, phead);
2840 /* _rtw_spinunlock(&pdefrag_q->lock); */
2842 /* call recvframe_defrag to defrag */
2843 precv_frame = recvframe_defrag(padapter, pdefrag_q);
2844 prtnframe = precv_frame;
2847 /* can't find this ta's defrag_queue, so free this recv_frame */
2848 rtw_free_recvframe(precv_frame, pfree_recv_queue);
2855 if ((prtnframe != NULL) && (prtnframe->u.hdr.attrib.privacy)) {
2856 /* after defrag we must check tkip mic code */
2857 if (recvframe_chkmic(padapter, prtnframe) == _FAIL) {
2858 rtw_free_recvframe(prtnframe, pfree_recv_queue);
2868 static int rtw_recv_indicatepkt_check(union recv_frame *rframe, u8 *ehdr_pos, u32 pkt_len)
2870 _adapter *adapter = rframe->u.hdr.adapter;
2871 struct recv_priv *recvpriv = &adapter->recvpriv;
2872 struct ethhdr *ehdr = (struct ethhdr *)ehdr_pos;
2875 #ifdef CONFIG_WAPI_SUPPORT
2876 if (rtw_wapi_check_for_drop(adapter, rframe, ehdr_pos)) {
2877 #ifdef DBG_RX_DROP_FRAME
2878 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" rtw_wapi_check_for_drop\n"
2879 , FUNC_ADPT_ARG(adapter));
2885 if (rframe->u.hdr.psta)
2886 rtw_st_ctl_rx(rframe->u.hdr.psta, ehdr_pos);
2888 if (ntohs(ehdr->h_proto) == 0x888e)
2889 parsing_eapol_packet(adapter, ehdr_pos + ETH_HLEN, rframe->u.hdr.psta, 0);
2891 else if (ntohs(ehdr->h_proto) == ETH_P_ARP)
2892 dump_arp_pkt(RTW_DBGDUMP, ehdr->h_dest, ehdr->h_source, ehdr_pos + ETH_HLEN, 0);
2895 if (recvpriv->sink_udpport > 0)
2896 rtw_sink_rtp_seq_dbg(adapter, ehdr_pos);
2898 #ifdef DBG_UDP_PKT_LOSE_11AC
2899 #define PAYLOAD_LEN_LOC_OF_IP_HDR 0x10 /*ethernet payload length location of ip header (DA + SA+eth_type+(version&hdr_len)) */
2901 if (ntohs(ehdr->h_proto) == ETH_P_ARP) {
2902 /* ARP Payload length will be 42bytes or 42+18(tailer)=60bytes*/
2903 if (pkt_len != 42 && pkt_len != 60)
2904 RTW_INFO("Error !!%s,ARP Payload length %u not correct\n" , __func__ , pkt_len);
2905 } else if (ntohs(ehdr->h_proto) == ETH_P_IP) {
2906 if (be16_to_cpu(*((u16 *)(ehdr_pos + PAYLOAD_LEN_LOC_OF_IP_HDR))) != (pkt_len) - ETH_HLEN) {
2907 RTW_INFO("Error !!%s,Payload length not correct\n" , __func__);
2908 RTW_INFO("%s, IP header describe Total length=%u\n" , __func__ , be16_to_cpu(*((u16 *)(ehdr_pos + PAYLOAD_LEN_LOC_OF_IP_HDR))));
2909 RTW_INFO("%s, Pkt real length=%u\n" , __func__ , (pkt_len) - ETH_HLEN);
2914 #ifdef CONFIG_AUTO_AP_MODE
2915 if (ntohs(ehdr->h_proto) == 0x8899)
2916 rtw_auto_ap_rx_msg_dump(adapter, rframe, ehdr_pos);
2921 #ifdef CONFIG_WAPI_SUPPORT
2927 static void recv_free_fwd_resource(_adapter *adapter, struct xmit_frame *fwd_frame, _list *b2u_list)
2929 struct xmit_priv *xmitpriv = &adapter->xmitpriv;
2932 rtw_free_xmitframe(xmitpriv, fwd_frame);
2934 #ifdef CONFIG_RTW_MESH
2935 #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
2936 if (!rtw_is_list_empty(b2u_list)) {
2937 struct xmit_frame *b2uframe;
2940 list = get_next(b2u_list);
2941 while (rtw_end_of_queue_search(b2u_list, list) == _FALSE) {
2942 b2uframe = LIST_CONTAINOR(list, struct xmit_frame, list);
2943 list = get_next(list);
2944 rtw_list_delete(&b2uframe->list);
2945 rtw_free_xmitframe(xmitpriv, b2uframe);
2949 #endif /* CONFIG_RTW_MESH */
2952 #ifdef CONFIG_RTW_MESH
2953 static void recv_fwd_pkt_hdl(_adapter *adapter, _pkt *pkt
2954 , u8 act, struct xmit_frame *fwd_frame, _list *b2u_list)
2956 struct xmit_priv *xmitpriv = &adapter->xmitpriv;
2957 _pkt *fwd_pkt = pkt;
2959 if (act & RTW_RX_MSDU_ACT_INDICATE) {
2960 fwd_pkt = rtw_os_pkt_copy(pkt);
2962 #ifdef DBG_TX_DROP_FRAME
2963 RTW_INFO("DBG_TX_DROP_FRAME %s rtw_os_pkt_copy fail\n", __func__);
2965 recv_free_fwd_resource(adapter, fwd_frame, b2u_list);
2970 #if CONFIG_RTW_MESH_DATA_BMC_TO_UC
2971 if (!rtw_is_list_empty(b2u_list)) {
2972 _list *list = get_next(b2u_list);
2973 struct xmit_frame *b2uframe;
2975 while (rtw_end_of_queue_search(b2u_list, list) == _FALSE) {
2976 b2uframe = LIST_CONTAINOR(list, struct xmit_frame, list);
2977 list = get_next(list);
2978 rtw_list_delete(&b2uframe->list);
2980 if (!fwd_frame && rtw_is_list_empty(b2u_list)) /* the last fwd_pkt */
2981 b2uframe->pkt = fwd_pkt;
2983 b2uframe->pkt = rtw_os_pkt_copy(fwd_pkt);
2984 if (!b2uframe->pkt) {
2985 rtw_free_xmitframe(xmitpriv, b2uframe);
2989 rtw_xmit_posthandle(adapter, b2uframe, b2uframe->pkt);
2995 fwd_frame->pkt = fwd_pkt;
2996 if (rtw_xmit_posthandle(adapter, fwd_frame, fwd_pkt) < 0) {
2997 #ifdef DBG_TX_DROP_FRAME
2998 RTW_INFO("DBG_TX_DROP_FRAME %s rtw_xmit_posthandle fail\n", __func__);
3000 xmitpriv->tx_drop++;
3007 #endif /* CONFIG_RTW_MESH */
3009 int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
3011 struct rx_pkt_attrib *rattrib = &prframe->u.hdr.attrib;
3012 int a_len, padding_len;
3013 u16 nSubframe_Length;
3016 _pkt *sub_pkt, *subframes[MAX_SUBFRAME_COUNT];
3017 struct recv_priv *precvpriv = &padapter->recvpriv;
3018 _queue *pfree_recv_queue = &(precvpriv->free_recv_queue);
3021 struct xmit_frame *fwd_frame;
3028 recvframe_pull(prframe, rattrib->hdrlen);
3030 if (rattrib->iv_len > 0)
3031 recvframe_pull(prframe, rattrib->iv_len);
3033 a_len = prframe->u.hdr.len;
3034 pdata = prframe->u.hdr.rx_data;
3036 while (a_len > ETH_HLEN) {
3037 /* Offset 12 denote 2 mac address */
3038 nSubframe_Length = RTW_GET_BE16(pdata + 12);
3039 if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) {
3040 RTW_INFO("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
3044 act = RTW_RX_MSDU_ACT_INDICATE;
3047 #ifdef CONFIG_RTW_MESH
3048 if (MLME_IS_MESH(padapter)) {
3049 u8 *mda = pdata, *msa = pdata + ETH_ALEN;
3050 struct rtw_ieee80211s_hdr *mctrl = (struct rtw_ieee80211s_hdr *)(pdata + ETH_HLEN);
3053 v_ret = rtw_mesh_rx_data_validate_mctrl(padapter, prframe
3054 , mctrl, mda, msa, &mctrl_len, &da, &sa);
3055 if (v_ret != _SUCCESS)
3058 act = rtw_mesh_rx_msdu_act_check(prframe
3059 , mda, msa, da, sa, mctrl, &fwd_frame, &b2u_list);
3064 sa = pdata + ETH_ALEN;
3070 rtw_led_rx_control(padapter, da);
3072 sub_pkt = rtw_os_alloc_msdu_pkt(prframe, da, sa
3073 , pdata + ETH_HLEN + mctrl_len, nSubframe_Length - mctrl_len);
3074 if (sub_pkt == NULL) {
3075 if (act & RTW_RX_MSDU_ACT_INDICATE) {
3076 #ifdef DBG_RX_DROP_FRAME
3077 RTW_INFO("DBG_RX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__);
3080 if (act & RTW_RX_MSDU_ACT_FORWARD) {
3081 #ifdef DBG_TX_DROP_FRAME
3082 RTW_INFO("DBG_TX_DROP_FRAME %s rtw_os_alloc_msdu_pkt fail\n", __func__);
3084 recv_free_fwd_resource(padapter, fwd_frame, &b2u_list);
3089 #ifdef CONFIG_RTW_MESH
3090 if (act & RTW_RX_MSDU_ACT_FORWARD) {
3091 recv_fwd_pkt_hdl(padapter, sub_pkt, act, fwd_frame, &b2u_list);
3092 if (!(act & RTW_RX_MSDU_ACT_INDICATE))
3097 if (rtw_recv_indicatepkt_check(prframe, rtw_os_pkt_data(sub_pkt), rtw_os_pkt_len(sub_pkt)) == _SUCCESS)
3098 subframes[nr_subframes++] = sub_pkt;
3100 rtw_os_pkt_free(sub_pkt);
3103 /* move the data point to data content */
3107 if (nr_subframes >= MAX_SUBFRAME_COUNT) {
3108 RTW_WARN("ParseSubframe(): Too many Subframes! Packets dropped!\n");
3112 pdata += nSubframe_Length;
3113 a_len -= nSubframe_Length;
3115 padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1));
3116 if (padding_len == 4)
3119 if (a_len < padding_len) {
3120 RTW_INFO("ParseSubframe(): a_len < padding_len !\n");
3123 pdata += padding_len;
3124 a_len -= padding_len;
3128 for (i = 0; i < nr_subframes; i++) {
3129 sub_pkt = subframes[i];
3131 /* Indicat the packets to upper layer */
3133 rtw_os_recv_indicate_pkt(padapter, sub_pkt, prframe);
3136 prframe->u.hdr.len = 0;
3137 rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
3142 static int recv_process_mpdu(_adapter *padapter, union recv_frame *prframe)
3144 _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3145 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3148 if (pattrib->amsdu) {
3149 ret = amsdu_to_msdu(padapter, prframe);
3150 if (ret != _SUCCESS) {
3151 #ifdef DBG_RX_DROP_FRAME
3152 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" amsdu_to_msdu fail\n"
3153 , FUNC_ADPT_ARG(padapter));
3155 rtw_free_recvframe(prframe, pfree_recv_queue);
3159 int act = RTW_RX_MSDU_ACT_INDICATE;
3160 struct xmit_frame *fwd_frame = NULL;
3163 #ifdef CONFIG_RTW_MESH
3164 if (MLME_IS_MESH(padapter) && pattrib->mesh_ctrl_present) {
3165 act = rtw_mesh_rx_msdu_act_check(prframe
3166 , pattrib->mda, pattrib->msa
3167 , pattrib->dst, pattrib->src
3168 , (struct rtw_ieee80211s_hdr *)(get_recvframe_data(prframe) + pattrib->hdrlen + pattrib->iv_len)
3169 , &fwd_frame, &b2u_list);
3174 rtw_free_recvframe(prframe, pfree_recv_queue);
3179 rtw_led_rx_control(padapter, pattrib->dst);
3181 ret = wlanhdr_to_ethhdr(prframe);
3182 if (ret != _SUCCESS) {
3183 if (act & RTW_RX_MSDU_ACT_INDICATE) {
3184 #ifdef DBG_RX_DROP_FRAME
3185 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" wlanhdr_to_ethhdr: drop pkt\n"
3186 , FUNC_ADPT_ARG(padapter));
3189 if (act & RTW_RX_MSDU_ACT_FORWARD) {
3190 #ifdef DBG_TX_DROP_FRAME
3191 RTW_INFO("DBG_TX_DROP_FRAME %s wlanhdr_to_ethhdr fail\n", __func__);
3193 recv_free_fwd_resource(padapter, fwd_frame, &b2u_list);
3195 rtw_free_recvframe(prframe, pfree_recv_queue);
3199 #ifdef CONFIG_RTW_MESH
3200 if (act & RTW_RX_MSDU_ACT_FORWARD) {
3201 recv_fwd_pkt_hdl(padapter, prframe->u.hdr.pkt, act, fwd_frame, &b2u_list);
3202 if (!(act & RTW_RX_MSDU_ACT_INDICATE)) {
3203 prframe->u.hdr.pkt = NULL;
3204 rtw_free_recvframe(prframe, pfree_recv_queue);
3210 if (!RTW_CANNOT_RUN(padapter)) {
3211 ret = rtw_recv_indicatepkt_check(prframe
3212 , get_recvframe_data(prframe), get_recvframe_len(prframe));
3213 if (ret != _SUCCESS) {
3214 rtw_free_recvframe(prframe, pfree_recv_queue);
3218 /* indicate this recv_frame */
3219 ret = rtw_recv_indicatepkt(padapter, prframe);
3220 if (ret != _SUCCESS) {
3221 #ifdef DBG_RX_DROP_FRAME
3222 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" rtw_recv_indicatepkt fail!\n"
3223 , FUNC_ADPT_ARG(padapter));
3228 #ifdef DBG_RX_DROP_FRAME
3229 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" DS:%u SR:%u\n"
3230 , FUNC_ADPT_ARG(padapter)
3231 , rtw_is_drv_stopped(padapter)
3232 , rtw_is_surprise_removed(padapter));
3234 ret = _SUCCESS; /* don't count as packet drop */
3235 rtw_free_recvframe(prframe, pfree_recv_queue);
3243 #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
3244 static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
3246 PADAPTER padapter = preorder_ctrl->padapter;
3247 struct recv_priv *precvpriv = &padapter->recvpriv;
3248 u8 wsize = preorder_ctrl->wsize_b;
3249 u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF; /* % 4096; */
3251 /* Rx Reorder initialize condition. */
3252 if (preorder_ctrl->indicate_seq == 0xFFFF) {
3253 preorder_ctrl->indicate_seq = seq_num;
3255 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_INIT indicate_seq:%d, seq_num:%d\n"
3256 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3260 /* Drop out the packet which SeqNum is smaller than WinStart */
3261 if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) {
3262 #ifdef DBG_RX_DROP_FRAME
3263 RTW_INFO(FUNC_ADPT_FMT" tid:%u indicate_seq:%d > seq_num:%d\n"
3264 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3270 * Sliding window manipulation. Conditions includes:
3271 * 1. Incoming SeqNum is equal to WinStart =>Window shift 1
3272 * 2. Incoming SeqNum is larger than the WinEnd => Window shift N
3274 if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
3275 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3277 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_EQUAL indicate_seq:%d, seq_num:%d\n"
3278 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3281 } else if (SN_LESS(wend, seq_num)) {
3282 /* boundary situation, when seq_num cross 0xFFF */
3283 if (seq_num >= (wsize - 1))
3284 preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
3286 preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
3288 precvpriv->dbg_rx_ampdu_window_shift_cnt++;
3290 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_LESS(wend, seq_num) indicate_seq:%d, seq_num:%d\n"
3291 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, seq_num);
3298 static int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe)
3300 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3301 _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3302 _list *phead, *plist;
3303 union recv_frame *pnextrframe;
3304 struct rx_pkt_attrib *pnextattrib;
3306 /* DbgPrint("+enqueue_reorder_recvframe()\n"); */
3308 /* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3309 /* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3312 phead = get_list_head(ppending_recvframe_queue);
3313 plist = get_next(phead);
3315 while (rtw_end_of_queue_search(phead, plist) == _FALSE) {
3316 pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
3317 pnextattrib = &pnextrframe->u.hdr.attrib;
3319 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
3320 plist = get_next(plist);
3321 else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
3322 /* Duplicate entry is found!! Do not insert current entry. */
3324 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3330 /* DbgPrint("enqueue_reorder_recvframe():while\n"); */
3335 /* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3336 /* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3338 rtw_list_delete(&(prframe->u.hdr.list));
3340 rtw_list_insert_tail(&(prframe->u.hdr.list), plist);
3342 /* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3343 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3350 static void recv_indicatepkts_pkt_loss_cnt(_adapter *padapter, u64 prev_seq, u64 current_seq)
3352 struct recv_priv *precvpriv = &padapter->recvpriv;
3354 if (current_seq < prev_seq) {
3355 precvpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq);
3356 precvpriv->rx_drop += (4096 + current_seq - prev_seq);
3358 precvpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq);
3359 precvpriv->rx_drop += (current_seq - prev_seq);
3363 static int recv_indicatepkts_in_order(_adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
3366 _list *phead, *plist;
3367 union recv_frame *prframe;
3368 struct rx_pkt_attrib *pattrib;
3370 int bPktInBuf = _FALSE;
3371 struct recv_priv *precvpriv = &padapter->recvpriv;
3372 _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3374 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder);
3376 /* DbgPrint("+recv_indicatepkts_in_order\n"); */
3378 /* _enter_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3379 /* _rtw_spinlock_ex(&ppending_recvframe_queue->lock); */
3381 phead = get_list_head(ppending_recvframe_queue);
3382 plist = get_next(phead);
3385 /* Check if there is any other indication thread running. */
3386 if (pTS->RxIndicateState == RXTS_INDICATE_PROCESSING)
3390 /* Handling some condition for forced indicate case. */
3391 if (bforced == _TRUE) {
3392 precvpriv->dbg_rx_ampdu_forced_indicate_count++;
3393 if (rtw_is_list_empty(phead)) {
3394 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3395 /* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3399 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3400 pattrib = &prframe->u.hdr.attrib;
3403 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u FORCE indicate_seq:%d, seq_num:%d\n"
3404 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pattrib->seq_num);
3406 recv_indicatepkts_pkt_loss_cnt(padapter, preorder_ctrl->indicate_seq, pattrib->seq_num);
3407 preorder_ctrl->indicate_seq = pattrib->seq_num;
3410 /* Prepare indication list and indication. */
3411 /* Check if there is any packet need indicate. */
3412 while (!rtw_is_list_empty(phead)) {
3414 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3415 pattrib = &prframe->u.hdr.attrib;
3417 if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
3420 /* This protect buffer from overflow. */
3421 if (index >= REORDER_WIN_SIZE) {
3422 RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!!\n"));
3428 plist = get_next(plist);
3429 rtw_list_delete(&(prframe->u.hdr.list));
3431 if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
3432 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3434 RTW_INFO("DBG_RX_SEQ "FUNC_ADPT_FMT" tid:%u SN_EQUAL indicate_seq:%d, seq_num:%d\n"
3435 , FUNC_ADPT_ARG(padapter), preorder_ctrl->tid, preorder_ctrl->indicate_seq, pattrib->seq_num);
3442 /* Cancel previous pending timer. */
3443 /* PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer); */
3444 if (bforced != _TRUE) {
3445 /* RTW_INFO("_cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);\n"); */
3446 _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
3451 /* Set this as a lock to make sure that only one thread is indicating packet. */
3452 /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */
3454 /* Indicate packets */
3455 /* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */
3458 /* indicate this recv_frame */
3459 /* DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num); */
3460 if (recv_process_mpdu(padapter, prframe) != _SUCCESS)
3461 precvpriv->dbg_rx_drop_count++;
3463 /* Update local variables. */
3471 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
3475 /* _rtw_spinunlock_ex(&ppending_recvframe_queue->lock); */
3476 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3479 /* Release the indication lock and set to new indication step. */
3481 /* Set new pending timer. */
3482 /* pTS->RxIndicateState = RXTS_INDICATE_REORDER; */
3483 /* PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime); */
3485 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3487 /* pTS->RxIndicateState = RXTS_INDICATE_IDLE; */
3490 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3497 static int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe)
3500 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3501 struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl;
3502 _queue *ppending_recvframe_queue = preorder_ctrl ? &preorder_ctrl->pending_recvframe_queue : NULL;
3503 struct recv_priv *precvpriv = &padapter->recvpriv;
3505 if (!pattrib->qos || !preorder_ctrl || preorder_ctrl->enable == _FALSE)
3508 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder);
3510 _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3512 /* s2. check if winstart_b(indicate_seq) needs to been updated */
3513 if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
3514 precvpriv->dbg_rx_ampdu_drop_count++;
3515 /* pHTInfo->RxReorderDropCounter++; */
3516 /* ReturnRFDList(Adapter, pRfd); */
3517 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3520 #ifdef DBG_RX_DROP_FRAME
3521 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" check_indicate_seq fail\n"
3522 , FUNC_ADPT_ARG(padapter));
3525 rtw_recv_indicatepkt(padapter, prframe);
3527 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3536 /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
3537 if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) {
3538 /* DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); */
3539 /* _exit_critical_ex(&ppending_recvframe_queue->lock, &irql); */
3541 #ifdef DBG_RX_DROP_FRAME
3542 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" enqueue_reorder_recvframe fail\n"
3543 , FUNC_ADPT_ARG(padapter));
3550 /* Indication process. */
3551 /* After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
3552 /* with the SeqNum smaller than latest WinStart and buffer other packets. */
3554 /* For Rx Reorder condition: */
3555 /* 1. All packets with SeqNum smaller than WinStart => Indicate */
3556 /* 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
3559 /* recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE); */
3560 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE) == _TRUE) {
3561 if (!preorder_ctrl->bReorderWaiting) {
3562 preorder_ctrl->bReorderWaiting = _TRUE;
3563 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3565 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3567 preorder_ctrl->bReorderWaiting = _FALSE;
3568 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3569 _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
3572 return RTW_RX_HANDLED;
3580 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3586 void rtw_reordering_ctrl_timeout_handler(void *pcontext)
3589 struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
3590 _adapter *padapter = preorder_ctrl->padapter;
3591 _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3594 if (RTW_CANNOT_RUN(padapter))
3597 /* RTW_INFO("+rtw_reordering_ctrl_timeout_handler()=>\n"); */
3599 _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3602 preorder_ctrl->bReorderWaiting = _FALSE;
3604 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE) == _TRUE)
3605 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3607 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3610 #endif /* defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL) */
3612 static void recv_set_iseq_before_mpdu_process(union recv_frame *rframe, u16 seq_num, const char *caller)
3614 #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
3615 struct recv_reorder_ctrl *reorder_ctrl = rframe->u.hdr.preorder_ctrl;
3618 reorder_ctrl->indicate_seq = seq_num;
3620 RTW_INFO("DBG_RX_SEQ %s("ADPT_FMT")-B tid:%u indicate_seq:%d, seq_num:%d\n"
3621 , caller, ADPT_ARG(reorder_ctrl->padapter)
3622 , reorder_ctrl->tid, reorder_ctrl->indicate_seq, seq_num);
3628 static void recv_set_iseq_after_mpdu_process(union recv_frame *rframe, u16 seq_num, const char *caller)
3630 #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
3631 struct recv_reorder_ctrl *reorder_ctrl = rframe->u.hdr.preorder_ctrl;
3634 reorder_ctrl->indicate_seq = (reorder_ctrl->indicate_seq + 1) % 4096;
3636 RTW_INFO("DBG_RX_SEQ %s("ADPT_FMT")-A tid:%u indicate_seq:%d, seq_num:%d\n"
3637 , caller, ADPT_ARG(reorder_ctrl->padapter)
3638 , reorder_ctrl->tid, reorder_ctrl->indicate_seq, seq_num);
3644 #ifdef CONFIG_MP_INCLUDED
3645 int validate_mp_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
3648 u8 *ptr = precv_frame->u.hdr.rx_data;
3650 struct mp_priv *pmppriv = &adapter->mppriv;
3651 struct mp_tx *pmptx;
3652 unsigned char *sa , *da, *bs;
3654 pmptx = &pmppriv->tx;
3659 type = GetFrameType(ptr);
3660 subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
3662 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
3663 if (bDumpRxPkt == 1) { /* dump all rx packets */
3665 RTW_INFO("############ type:0x%02x subtype:0x%02x #################\n", type, subtype);
3667 for (i = 0; i < 64; i = i + 8)
3668 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
3669 *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
3670 RTW_INFO("#############################\n");
3674 if (pmppriv->bloopback) {
3675 if (_rtw_memcmp(ptr + 24, pmptx->buf + 24, precv_frame->u.hdr.len - 24) == _FALSE) {
3676 RTW_INFO("Compare payload content Fail !!!\n");
3680 if (pmppriv->bSetRxBssid == _TRUE) {
3682 sa = get_addr2_ptr(ptr);
3683 da = GetAddr1Ptr(ptr);
3684 bs = GetAddr3Ptr(ptr);
3685 type = GetFrameType(ptr);
3686 subtype = get_frame_sub_type(ptr); /* bit(7)~bit(2) */
3688 if (_rtw_memcmp(bs, adapter->mppriv.network_macaddr, ETH_ALEN) == _FALSE)
3691 RTW_DBG("############ type:0x%02x subtype:0x%02x #################\n", type, subtype);
3692 RTW_DBG("A2 sa %02X:%02X:%02X:%02X:%02X:%02X \n", *(sa) , *(sa + 1), *(sa+ 2), *(sa + 3), *(sa + 4), *(sa + 5));
3693 RTW_DBG("A1 da %02X:%02X:%02X:%02X:%02X:%02X \n", *(da) , *(da + 1), *(da+ 2), *(da + 3), *(da + 4), *(da + 5));
3694 RTW_DBG("A3 bs %02X:%02X:%02X:%02X:%02X:%02X \n --------------------------\n", *(bs) , *(bs + 1), *(bs+ 2), *(bs + 3), *(bs + 4), *(bs + 5));
3697 if (!adapter->mppriv.bmac_filter)
3700 if (_rtw_memcmp(get_addr2_ptr(ptr), adapter->mppriv.mac_filter, ETH_ALEN) == _FALSE)
3706 static sint MPwlanhdr_to_ethhdr(union recv_frame *precvframe)
3712 u8 mcastheadermac[] = {0x01, 0x00, 0x5e};
3714 struct ieee80211_snap_hdr *psnap;
3716 sint ret = _SUCCESS;
3717 _adapter *adapter = precvframe->u.hdr.adapter;
3719 u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */
3720 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
3723 if (pattrib->encrypt)
3724 recvframe_pull_tail(precvframe, pattrib->icv_len);
3726 psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
3727 psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
3728 /* convert hdr + possible LLC headers into Ethernet header */
3729 /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
3730 if ((_rtw_memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
3731 (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) == _FALSE) &&
3732 (_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2) == _FALSE)) ||
3733 /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */
3734 _rtw_memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
3735 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
3738 /* Leave Ethernet header part of hdr and full payload */
3742 rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
3743 len = precvframe->u.hdr.len - rmv_len;
3746 _rtw_memcpy(ð_type, ptr + rmv_len, 2);
3747 eth_type = ntohs((unsigned short)eth_type); /* pattrib->ether_type */
3748 pattrib->eth_type = eth_type;
3751 ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
3754 _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
3755 _rtw_memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
3759 _rtw_memcpy(ptr + 12, &len, 2);
3763 len = htons(pattrib->seq_num);
3764 /* RTW_INFO("wlan seq = %d ,seq_num =%x\n",len,pattrib->seq_num); */
3765 _rtw_memcpy(ptr + 12, &len, 2);
3766 if (adapter->mppriv.bRTWSmbCfg == _TRUE) {
3767 /* if(_rtw_memcmp(mcastheadermac, pattrib->dst, 3) == _TRUE) */ /* SimpleConfig Dest. */
3768 /* _rtw_memcpy(ptr+ETH_ALEN, pattrib->bssid, ETH_ALEN); */
3770 if (_rtw_memcmp(mcastheadermac, pattrib->bssid, 3) == _TRUE) /* SimpleConfig Dest. */
3771 _rtw_memcpy(ptr, pattrib->bssid, ETH_ALEN);
3781 int mp_recv_frame(_adapter *padapter, union recv_frame *rframe)
3784 struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
3785 _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
3786 #ifdef CONFIG_MP_INCLUDED
3787 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3788 struct mp_priv *pmppriv = &padapter->mppriv;
3789 #endif /* CONFIG_MP_INCLUDED */
3791 u8 *ptr = rframe->u.hdr.rx_data;
3792 u8 *psa, *pda, *pbssid;
3793 struct sta_info *psta = NULL;
3794 DBG_COUNTER(padapter->rx_logs.core_rx_pre);
3796 if ((check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE)) { /* &&(padapter->mppriv.check_mp_pkt == 0)) */
3797 if (pattrib->crc_err == 1)
3798 padapter->mppriv.rx_crcerrpktcount++;
3800 if (_SUCCESS == validate_mp_recv_frame(padapter, rframe))
3801 padapter->mppriv.rx_pktcount++;
3803 padapter->mppriv.rx_pktcount_filter_out++;
3806 if (pmppriv->rx_bindicatePkt == _FALSE) {
3808 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3811 type = GetFrameType(ptr);
3812 pattrib->to_fr_ds = get_tofr_ds(ptr);
3813 pattrib->frag_num = GetFragNum(ptr);
3814 pattrib->seq_num = GetSequence(ptr);
3815 pattrib->pw_save = GetPwrMgt(ptr);
3816 pattrib->mfrag = GetMFrag(ptr);
3817 pattrib->mdata = GetMData(ptr);
3818 pattrib->privacy = GetPrivacy(ptr);
3819 pattrib->order = GetOrder(ptr);
3821 if (type == WIFI_DATA_TYPE) {
3824 pbssid = get_hdr_bssid(ptr);
3826 _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
3827 _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
3828 _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
3830 switch (pattrib->to_fr_ds) {
3832 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
3833 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
3834 ret = sta2sta_data_frame(padapter, rframe, &psta);
3839 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
3840 _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
3841 ret = ap2sta_data_frame(padapter, rframe, &psta);
3846 _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
3847 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
3848 ret = sta2ap_data_frame(padapter, rframe, &psta);
3852 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
3853 _rtw_memcpy(pattrib->ta, get_addr2_ptr(ptr), ETH_ALEN);
3862 ret = MPwlanhdr_to_ethhdr(rframe);
3864 if (ret != _SUCCESS) {
3865 #ifdef DBG_RX_DROP_FRAME
3866 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" wlanhdr_to_ethhdr: drop pkt\n"
3867 , FUNC_ADPT_ARG(padapter));
3869 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3873 if (!RTW_CANNOT_RUN(padapter)) {
3874 /* indicate this recv_frame */
3875 ret = rtw_recv_indicatepkt(padapter, rframe);
3876 if (ret != _SUCCESS) {
3877 #ifdef DBG_RX_DROP_FRAME
3878 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" rtw_recv_indicatepkt fail!\n"
3879 , FUNC_ADPT_ARG(padapter));
3881 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3887 #ifdef DBG_RX_DROP_FRAME
3888 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
3889 , FUNC_ADPT_ARG(padapter)
3890 , rtw_is_drv_stopped(padapter) ? "True" : "False"
3891 , rtw_is_surprise_removed(padapter) ? "True" : "False");
3894 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3903 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
3912 static sint fill_radiotap_hdr(_adapter *padapter, union recv_frame *precvframe, u8 *buf)
3914 #define CHAN2FREQ(a) ((a < 14) ? (2407+5*a) : (5000+5*a))
3917 #define RTW_RX_RADIOTAP_PRESENT (\
3918 (1 << IEEE80211_RADIOTAP_TSFT) | \
3919 (1 << IEEE80211_RADIOTAP_FLAGS) | \
3920 (1 << IEEE80211_RADIOTAP_RATE) | \
3921 (1 << IEEE80211_RADIOTAP_CHANNEL) | \
3922 (0 << IEEE80211_RADIOTAP_FHSS) | \
3923 (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
3924 (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
3925 (0 << IEEE80211_RADIOTAP_LOCK_QUALITY) | \
3926 (0 << IEEE80211_RADIOTAP_TX_ATTENUATION) | \
3927 (0 << IEEE80211_RADIOTAP_DB_TX_ATTENUATION) | \
3928 (0 << IEEE80211_RADIOTAP_DBM_TX_POWER) | \
3929 (1 << IEEE80211_RADIOTAP_ANTENNA) | \
3930 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
3931 (0 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \
3932 (0 << IEEE80211_RADIOTAP_RX_FLAGS) | \
3933 (0 << IEEE80211_RADIOTAP_TX_FLAGS) | \
3934 (0 << IEEE80211_RADIOTAP_RTS_RETRIES) | \
3935 (0 << IEEE80211_RADIOTAP_DATA_RETRIES) | \
3936 (0 << IEEE80211_RADIOTAP_MCS) | \
3937 (0 << IEEE80211_RADIOTAP_RADIOTAP_NAMESPACE)| \
3938 (0 << IEEE80211_RADIOTAP_VENDOR_NAMESPACE) | \
3939 (0 << IEEE80211_RADIOTAP_EXT) | \
3942 /* (0 << IEEE80211_RADIOTAP_AMPDU_STATUS) | \ */
3943 /* (0 << IEEE80211_RADIOTAP_VHT) | \ */
3946 #ifndef IEEE80211_RADIOTAP_RX_FLAGS
3947 #define IEEE80211_RADIOTAP_RX_FLAGS 14
3950 #ifndef IEEE80211_RADIOTAP_MCS
3951 #define IEEE80211_RADIOTAP_MCS 19
3953 #ifndef IEEE80211_RADIOTAP_VHT
3954 #define IEEE80211_RADIOTAP_VHT 21
3957 #ifndef IEEE80211_RADIOTAP_F_BADFCS
3958 #define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* bad FCS */
3961 sint ret = _SUCCESS;
3962 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
3964 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3969 2, 4, 11, 22, /* CCK */
3970 12, 18, 24, 36, 48, 72, 93, 108, /* OFDM */
3971 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* HT MCS index */
3972 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
3973 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 1 */
3974 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 2 */
3975 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 3 */
3976 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* VHT Nss 4 */
3981 struct ieee80211_radiotap_header *rtap_hdr = NULL;
3984 u8 hdr_buf[64] = {0};
3988 rtap_hdr = (struct ieee80211_radiotap_header *)&hdr_buf[0];
3989 rtap_hdr->it_version = PKTHDR_RADIOTAP_VERSION;
3992 if (pattrib->tsfl) {
3995 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_TSFT);
3996 tmp_64bit = cpu_to_le64(pattrib->tsfl);
3997 memcpy(&hdr_buf[rt_len], &tmp_64bit, 8);
4002 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_FLAGS);
4004 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_CFP;
4007 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_SHORTPRE;
4009 if ((pattrib->encrypt == 1) || (pattrib->encrypt == 5))
4010 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_WEP;
4013 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FRAG;
4015 /* always append FCS */
4016 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_FCS;
4020 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_DATAPAD;
4022 if (pattrib->crc_err)
4023 hdr_buf[rt_len] |= IEEE80211_RADIOTAP_F_BADFCS;
4026 /* Currently unspecified but used */
4027 hdr_buf[rt_len] |= 0x80;
4032 if (pattrib->data_rate <= DESC_RATE54M) {
4033 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RATE);
4034 if (pattrib->data_rate <= DESC_RATE11M) {
4036 hdr_buf[rt_len] = data_rate[pattrib->data_rate];
4039 hdr_buf[rt_len] = data_rate[pattrib->data_rate];
4042 rt_len += 1; /* force padding 1 byte for aligned */
4046 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
4047 tmp_16bit = CHAN2FREQ(rtw_get_oper_ch(padapter));
4048 /*tmp_16bit = CHAN2FREQ(pHalData->current_channel);*/
4049 memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
4054 if (pHalData->current_band_type == 0)
4055 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_2GHZ);
4057 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_5GHZ);
4059 if (pattrib->data_rate <= DESC_RATE54M) {
4060 if (pattrib->data_rate <= DESC_RATE11M) {
4062 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_CCK);
4065 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_OFDM);
4068 tmp_16bit |= cpu_to_le16(IEEE80211_CHAN_DYN);
4069 memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
4072 /* dBm Antenna Signal */
4073 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL);
4074 hdr_buf[rt_len] = pattrib->phy_info.recv_signal_power;
4078 /* dBm Antenna Noise */
4079 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE);
4080 hdr_buf[rt_len] = 0;
4083 /* Signal Quality */
4084 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_LOCK_QUALITY);
4085 hdr_buf[rt_len] = pattrib->phy_info.signal_quality;
4090 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_ANTENNA);
4091 hdr_buf[rt_len] = 0; /* pHalData->rf_type; */
4095 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_RX_FLAGS);
4097 tmp_16bit = cpu_to_le16(0);
4098 memcpy(ptr, &tmp_16bit, 1);
4102 /* MCS information */
4103 if (pattrib->data_rate >= DESC_RATEMCS0 && pattrib->data_rate <= DESC_RATEMCS31) {
4104 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_MCS);
4106 hdr_buf[rt_len] |= BIT1; /* MCS index known */
4109 hdr_buf[rt_len] |= BIT0;
4110 hdr_buf[rt_len + 1] |= (pattrib->bw & 0x03);
4112 /* guard interval */
4113 hdr_buf[rt_len] |= BIT2;
4114 hdr_buf[rt_len + 1] |= (pattrib->sgi & 0x01) << 2;
4117 hdr_buf[rt_len] |= BIT5;
4118 hdr_buf[rt_len + 1] |= (pattrib->stbc & 0x03) << 5;
4122 /* MCS rate index */
4123 hdr_buf[rt_len] = data_rate[pattrib->data_rate];
4128 if (pattrib->data_rate >= DESC_RATEVHTSS1MCS0 && pattrib->data_rate <= DESC_RATEVHTSS4MCS9) {
4129 rtap_hdr->it_present |= (1 << IEEE80211_RADIOTAP_VHT);
4131 /* known 16 bit, flag 8 bit */
4145 hdr_buf[rt_len + 2] |= (pattrib->stbc & 0x01);
4147 /* Guard interval */
4149 hdr_buf[rt_len + 2] |= (pattrib->sgi & 0x01) << 2;
4151 /* LDPC extra OFDM symbol */
4153 hdr_buf[rt_len + 2] |= (pattrib->ldpc & 0x01) << 4;
4155 memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
4159 if (pattrib->bw == 0)
4160 hdr_buf[rt_len] |= 0;
4161 else if (pattrib->bw == 1)
4162 hdr_buf[rt_len] |= 1;
4163 else if (pattrib->bw == 2)
4164 hdr_buf[rt_len] |= 4;
4165 else if (pattrib->bw == 3)
4166 hdr_buf[rt_len] |= 11;
4170 if (pattrib->data_rate >= DESC_RATEVHTSS1MCS0 && pattrib->data_rate <= DESC_RATEVHTSS1MCS9) {
4171 hdr_buf[rt_len] |= 1;
4172 hdr_buf[rt_len] |= data_rate[pattrib->data_rate] << 4;
4173 } else if (pattrib->data_rate >= DESC_RATEVHTSS2MCS0 && pattrib->data_rate <= DESC_RATEVHTSS2MCS9) {
4174 hdr_buf[rt_len + 1] |= 2;
4175 hdr_buf[rt_len + 1] |= data_rate[pattrib->data_rate] << 4;
4176 } else if (pattrib->data_rate >= DESC_RATEVHTSS3MCS0 && pattrib->data_rate <= DESC_RATEVHTSS3MCS9) {
4177 hdr_buf[rt_len + 2] |= 3;
4178 hdr_buf[rt_len + 2] |= data_rate[pattrib->data_rate] << 4;
4179 } else if (pattrib->data_rate >= DESC_RATEVHTSS4MCS0 && pattrib->data_rate <= DESC_RATEVHTSS4MCS9) {
4180 hdr_buf[rt_len + 3] |= 4;
4181 hdr_buf[rt_len + 3] |= data_rate[pattrib->data_rate] << 4;
4186 hdr_buf[rt_len] = 0;
4190 hdr_buf[rt_len] = 0;
4195 memcpy(&hdr_buf[rt_len], &tmp_16bit, 2);
4201 if (skb_headroom(pskb) < rt_len) {
4202 RTW_INFO("%s:%d %s headroom is too small.\n", __FILE__, __LINE__, __func__);
4207 ptr = skb_push(pskb, rt_len);
4209 rtap_hdr->it_len = cpu_to_le16(rt_len);
4210 rtap_hdr->it_present = cpu_to_le32(rtap_hdr->it_present);
4211 memcpy(ptr, rtap_hdr, rt_len);
4218 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
4219 int recv_frame_monitor(_adapter *padapter, union recv_frame *rframe)
4222 _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4225 /* read skb information from recv frame */
4226 pskb = rframe->u.hdr.pkt;
4227 pskb->len = rframe->u.hdr.len;
4228 pskb->data = rframe->u.hdr.rx_data;
4229 skb_set_tail_pointer(pskb, rframe->u.hdr.len);
4231 /* fill radiotap header */
4232 if (fill_radiotap_hdr(padapter, rframe, (u8 *)pskb) == _FAIL) {
4234 rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4238 /* write skb information to recv frame */
4239 skb_reset_mac_header(pskb);
4240 rframe->u.hdr.len = pskb->len;
4241 rframe->u.hdr.rx_data = pskb->data;
4242 rframe->u.hdr.rx_head = pskb->head;
4243 rframe->u.hdr.rx_tail = skb_tail_pointer(pskb);
4244 rframe->u.hdr.rx_end = skb_end_pointer(pskb);
4246 if (!RTW_CANNOT_RUN(padapter)) {
4247 /* indicate this recv_frame */
4248 ret = rtw_recv_monitor(padapter, rframe);
4249 if (ret != _SUCCESS) {
4251 rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4256 rtw_free_recvframe(rframe, pfree_recv_queue); /* free this recv_frame */
4264 int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
4267 #ifdef DBG_RX_COUNTER_DUMP
4268 struct rx_pkt_attrib *pattrib = &rframe->u.hdr.attrib;
4270 _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4272 #ifdef DBG_RX_COUNTER_DUMP
4273 if (padapter->dump_rx_cnt_mode & DUMP_DRV_RX_COUNTER) {
4274 if (pattrib->crc_err == 1)
4275 padapter->drv_rx_cnt_crcerror++;
4277 padapter->drv_rx_cnt_ok++;
4281 #ifdef CONFIG_MP_INCLUDED
4282 if (padapter->registrypriv.mp_mode == 1 || padapter->mppriv.bRTWSmbCfg == _TRUE) {
4283 mp_recv_frame(padapter, rframe);
4289 /* check the frame crtl field and decache */
4290 ret = validate_recv_frame(padapter, rframe);
4291 if (ret != _SUCCESS) {
4292 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
4300 /*#define DBG_RX_BMC_FRAME*/
4301 int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
4304 union recv_frame *orig_prframe = prframe;
4305 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
4306 struct recv_priv *precvpriv = &padapter->recvpriv;
4307 _queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
4309 u8 *psnap_type, *pcategory;
4310 #endif /* CONFIG_TDLS */
4312 DBG_COUNTER(padapter->rx_logs.core_rx_post);
4314 prframe = decryptor(padapter, prframe);
4315 if (prframe == NULL) {
4316 #ifdef DBG_RX_DROP_FRAME
4317 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" decryptor: drop pkt\n"
4318 , FUNC_ADPT_ARG(padapter));
4321 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err);
4322 goto _recv_data_drop;
4325 #ifdef DBG_RX_BMC_FRAME
4326 if (IS_MCAST(pattrib->ra))
4327 RTW_INFO("%s =>"ADPT_FMT" Rx BC/MC from "MAC_FMT"\n", __func__, ADPT_ARG(padapter), MAC_ARG(pattrib->ta));
4331 if (is_primary_adapter(padapter)) {
4335 u8 *ptr = get_recvframe_data(prframe);
4336 for (i = 0; i < 140; i = i + 8)
4337 RTW_INFO("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr + i),
4338 *(ptr + i + 1), *(ptr + i + 2) , *(ptr + i + 3) , *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
4346 /* check TDLS frame */
4347 psnap_type = get_recvframe_data(orig_prframe) + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
4348 pcategory = psnap_type + ETH_TYPE_LEN + PAYLOAD_TYPE_LEN;
4350 if ((_rtw_memcmp(psnap_type, SNAP_ETH_TYPE_TDLS, ETH_TYPE_LEN)) &&
4351 ((*pcategory == RTW_WLAN_CATEGORY_TDLS) || (*pcategory == RTW_WLAN_CATEGORY_P2P))) {
4352 ret = OnTDLS(padapter, prframe);
4354 goto _exit_recv_func;
4356 #endif /* CONFIG_TDLS */
4358 prframe = recvframe_chk_defrag(padapter, prframe);
4359 if (prframe == NULL) {
4360 #ifdef DBG_RX_DROP_FRAME
4361 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" recvframe_chk_defrag: drop pkt\n"
4362 , FUNC_ADPT_ARG(padapter));
4364 DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err);
4365 goto _recv_data_drop;
4368 prframe = portctrl(padapter, prframe);
4369 if (prframe == NULL) {
4370 #ifdef DBG_RX_DROP_FRAME
4371 RTW_INFO("DBG_RX_DROP_FRAME "FUNC_ADPT_FMT" portctrl: drop pkt\n"
4372 , FUNC_ADPT_ARG(padapter));
4375 DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err);
4376 goto _recv_data_drop;
4379 count_rx_stats(padapter, prframe, NULL);
4381 #ifdef CONFIG_WAPI_SUPPORT
4382 rtw_wapi_update_info(padapter, prframe);
4385 #if defined(CONFIG_80211N_HT) && defined(CONFIG_RECV_REORDERING_CTRL)
4386 /* including perform A-MPDU Rx Ordering Buffer Control */
4387 ret = recv_indicatepkt_reorder(padapter, prframe);
4389 rtw_free_recvframe(orig_prframe, pfree_recv_queue);
4390 goto _recv_data_drop;
4391 } else if (ret == RTW_RX_HANDLED) /* queued OR indicated in order */
4392 goto _exit_recv_func;
4395 recv_set_iseq_before_mpdu_process(prframe, pattrib->seq_num, __func__);
4396 ret = recv_process_mpdu(padapter, prframe);
4397 recv_set_iseq_after_mpdu_process(prframe, pattrib->seq_num, __func__);
4399 goto _recv_data_drop;
4405 precvpriv->dbg_rx_drop_count++;
4409 int recv_func(_adapter *padapter, union recv_frame *rframe)
4412 struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib;
4413 struct recv_priv *recvpriv = &padapter->recvpriv;
4414 struct security_priv *psecuritypriv = &padapter->securitypriv;
4415 struct mlme_priv *mlmepriv = &padapter->mlmepriv;
4417 if (check_fwstate(mlmepriv, WIFI_MONITOR_STATE)) {
4419 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24))
4420 recv_frame_monitor(padapter, rframe);
4426 /* check if need to handle uc_swdec_pending_queue*/
4427 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) {
4428 union recv_frame *pending_frame;
4431 while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) {
4433 DBG_COUNTER(padapter->rx_logs.core_rx_dequeue);
4434 recv_func_posthandle(padapter, pending_frame);
4438 RTW_INFO(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n",
4439 FUNC_ADPT_ARG(padapter), cnt);
4442 DBG_COUNTER(padapter->rx_logs.core_rx);
4443 ret = recv_func_prehandle(padapter, rframe);
4445 if (ret == _SUCCESS) {
4447 /* check if need to enqueue into uc_swdec_pending_queue*/
4448 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
4449 !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 &&
4450 (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt == _TRUE) &&
4451 psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
4452 !psecuritypriv->busetkipkey) {
4453 DBG_COUNTER(padapter->rx_logs.core_rx_enqueue);
4454 rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
4455 /* RTW_INFO("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); */
4457 if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) {
4458 /* to prevent from recvframe starvation, get recvframe from uc_swdec_pending_queue to free_recvframe_cnt */
4459 rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
4467 ret = recv_func_posthandle(padapter, rframe);
4475 s32 rtw_recv_entry(union recv_frame *precvframe)
4478 struct recv_priv *precvpriv;
4483 padapter = precvframe->u.hdr.adapter;
4485 precvpriv = &padapter->recvpriv;
4488 ret = recv_func(padapter, precvframe);
4490 goto _recv_entry_drop;
4494 precvpriv->rx_pkts++;
4501 #ifdef CONFIG_MP_INCLUDED
4502 if (padapter->registrypriv.mp_mode == 1)
4503 padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
4511 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4512 static void rtw_signal_stat_timer_hdl(void *ctx)
4514 _adapter *adapter = (_adapter *)ctx;
4515 struct recv_priv *recvpriv = &adapter->recvpriv;
4518 u8 avg_signal_strength = 0;
4519 u8 avg_signal_qual = 0;
4520 u32 num_signal_strength = 0;
4521 u32 num_signal_qual = 0;
4522 u8 ratio_pre_stat = 0, ratio_curr_stat = 0, ratio_total = 0, ratio_profile = SIGNAL_STAT_CALC_PROFILE_0;
4524 if (adapter->recvpriv.is_signal_dbg) {
4525 /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
4526 adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
4527 adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
4530 if (recvpriv->signal_strength_data.update_req == 0) { /* update_req is clear, means we got rx */
4531 avg_signal_strength = recvpriv->signal_strength_data.avg_val;
4532 num_signal_strength = recvpriv->signal_strength_data.total_num;
4533 /* after avg_vals are accquired, we can re-stat the signal values */
4534 recvpriv->signal_strength_data.update_req = 1;
4537 if (recvpriv->signal_qual_data.update_req == 0) { /* update_req is clear, means we got rx */
4538 avg_signal_qual = recvpriv->signal_qual_data.avg_val;
4539 num_signal_qual = recvpriv->signal_qual_data.total_num;
4540 /* after avg_vals are accquired, we can re-stat the signal values */
4541 recvpriv->signal_qual_data.update_req = 1;
4544 if (num_signal_strength == 0) {
4545 if (rtw_get_on_cur_ch_time(adapter) == 0
4546 || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval
4551 if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE
4552 || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE
4556 #ifdef CONFIG_CONCURRENT_MODE
4557 if (rtw_mi_buddy_check_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE)
4561 if (RTW_SIGNAL_STATE_CALC_PROFILE < SIGNAL_STAT_CALC_PROFILE_MAX)
4562 ratio_profile = RTW_SIGNAL_STATE_CALC_PROFILE;
4564 ratio_pre_stat = signal_stat_calc_profile[ratio_profile][0];
4565 ratio_curr_stat = signal_stat_calc_profile[ratio_profile][1];
4566 ratio_total = ratio_pre_stat + ratio_curr_stat;
4568 /* update value of signal_strength, rssi, signal_qual */
4569 tmp_s = (ratio_curr_stat * avg_signal_strength + ratio_pre_stat * recvpriv->signal_strength);
4570 if (tmp_s % ratio_total)
4571 tmp_s = tmp_s / ratio_total + 1;
4573 tmp_s = tmp_s / ratio_total;
4577 tmp_q = (ratio_curr_stat * avg_signal_qual + ratio_pre_stat * recvpriv->signal_qual);
4578 if (tmp_q % ratio_total)
4579 tmp_q = tmp_q / ratio_total + 1;
4581 tmp_q = tmp_q / ratio_total;
4585 recvpriv->signal_strength = tmp_s;
4586 recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
4587 recvpriv->signal_qual = tmp_q;
4589 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
4590 RTW_INFO(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
4591 ", num_signal_strength:%u, num_signal_qual:%u"
4594 , FUNC_ADPT_ARG(adapter)
4595 , recvpriv->signal_strength
4597 , recvpriv->signal_qual
4598 , num_signal_strength, num_signal_qual
4599 , rtw_get_on_cur_ch_time(adapter) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter)) : 0
4605 rtw_set_signal_stat_timer(recvpriv);
4608 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4610 static void rx_process_rssi(_adapter *padapter, union recv_frame *prframe)
4612 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
4613 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4614 struct signal_stat *signal_stat = &padapter->recvpriv.signal_strength_data;
4615 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4616 u32 last_rssi, tmp_val;
4617 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4619 /* RTW_INFO("process_rssi=> pattrib->rssil(%d) signal_strength(%d)\n ",pattrib->recv_signal_power,pattrib->signal_strength); */
4620 /* if(pRfd->Status.bPacketToSelf || pRfd->Status.bPacketBeacon) */
4622 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4623 if (signal_stat->update_req) {
4624 signal_stat->total_num = 0;
4625 signal_stat->total_val = 0;
4626 signal_stat->update_req = 0;
4629 signal_stat->total_num++;
4630 signal_stat->total_val += pattrib->phy_info.signal_strength;
4631 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
4632 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4634 /* Adapter->RxStats.RssiCalculateCnt++; */ /* For antenna Test */
4635 if (padapter->recvpriv.signal_strength_data.total_num++ >= PHY_RSSI_SLID_WIN_MAX) {
4636 padapter->recvpriv.signal_strength_data.total_num = PHY_RSSI_SLID_WIN_MAX;
4637 last_rssi = padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index];
4638 padapter->recvpriv.signal_strength_data.total_val -= last_rssi;
4640 padapter->recvpriv.signal_strength_data.total_val += pattrib->phy_info.signal_strength;
4642 padapter->recvpriv.signal_strength_data.elements[padapter->recvpriv.signal_strength_data.index++] = pattrib->phy_info.signal_strength;
4643 if (padapter->recvpriv.signal_strength_data.index >= PHY_RSSI_SLID_WIN_MAX)
4644 padapter->recvpriv.signal_strength_data.index = 0;
4647 tmp_val = padapter->recvpriv.signal_strength_data.total_val / padapter->recvpriv.signal_strength_data.total_num;
4649 if (padapter->recvpriv.is_signal_dbg) {
4650 padapter->recvpriv.signal_strength = padapter->recvpriv.signal_strength_dbg;
4651 padapter->recvpriv.rssi = (s8)translate_percentage_to_dbm(padapter->recvpriv.signal_strength_dbg);
4653 padapter->recvpriv.signal_strength = tmp_val;
4654 padapter->recvpriv.rssi = (s8)translate_percentage_to_dbm(tmp_val);
4657 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4661 static void rx_process_link_qual(_adapter *padapter, union recv_frame *prframe)
4663 struct rx_pkt_attrib *pattrib;
4664 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4665 struct signal_stat *signal_stat;
4666 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4667 u32 last_evm = 0, tmpVal;
4668 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4670 if (prframe == NULL || padapter == NULL)
4673 pattrib = &prframe->u.hdr.attrib;
4674 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4675 signal_stat = &padapter->recvpriv.signal_qual_data;
4676 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4678 /* RTW_INFO("process_link_qual=> pattrib->signal_qual(%d)\n ",pattrib->signal_qual); */
4680 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4681 if (signal_stat->update_req) {
4682 signal_stat->total_num = 0;
4683 signal_stat->total_val = 0;
4684 signal_stat->update_req = 0;
4687 signal_stat->total_num++;
4688 signal_stat->total_val += pattrib->phy_info.signal_quality;
4689 signal_stat->avg_val = signal_stat->total_val / signal_stat->total_num;
4691 #else /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4692 if (pattrib->phy_info.signal_quality != 0) {
4694 /* 1. Record the general EVM to the sliding window. */
4696 if (padapter->recvpriv.signal_qual_data.total_num++ >= PHY_LINKQUALITY_SLID_WIN_MAX) {
4697 padapter->recvpriv.signal_qual_data.total_num = PHY_LINKQUALITY_SLID_WIN_MAX;
4698 last_evm = padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index];
4699 padapter->recvpriv.signal_qual_data.total_val -= last_evm;
4701 padapter->recvpriv.signal_qual_data.total_val += pattrib->phy_info.signal_quality;
4703 padapter->recvpriv.signal_qual_data.elements[padapter->recvpriv.signal_qual_data.index++] = pattrib->phy_info.signal_quality;
4704 if (padapter->recvpriv.signal_qual_data.index >= PHY_LINKQUALITY_SLID_WIN_MAX)
4705 padapter->recvpriv.signal_qual_data.index = 0;
4708 /* <1> Showed on UI for user, in percentage. */
4709 tmpVal = padapter->recvpriv.signal_qual_data.total_val / padapter->recvpriv.signal_qual_data.total_num;
4710 padapter->recvpriv.signal_qual = (u8)tmpVal;
4713 #endif /* CONFIG_NEW_SIGNAL_STAT_PROCESS */
4716 void rx_process_phy_info(_adapter *padapter, union recv_frame *rframe)
4719 rx_process_rssi(padapter, rframe);
4722 /* process_PWDB(padapter, rframe); */
4724 /* UpdateRxSignalStatistics8192C(Adapter, pRfd); */
4727 rx_process_link_qual(padapter, rframe);
4728 rtw_store_phy_info(padapter, rframe);
4731 void rx_query_phy_status(
4732 union recv_frame *precvframe,
4735 PADAPTER padapter = precvframe->u.hdr.adapter;
4736 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
4737 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4738 struct phydm_phyinfo_struct *p_phy_info = &pattrib->phy_info;
4740 struct phydm_perpkt_info_struct pkt_info;
4743 struct sta_priv *pstapriv;
4744 struct sta_info *psta = NULL;
4745 struct recv_priv *precvpriv = &padapter->recvpriv;
4748 pkt_info.is_packet_match_bssid = _FALSE;
4749 pkt_info.is_packet_to_self = _FALSE;
4750 pkt_info.is_packet_beacon = _FALSE;
4751 pkt_info.ppdu_cnt = pattrib->ppdu_cnt;
4752 pkt_info.station_id = 0xFF;
4754 wlanhdr = get_recvframe_data(precvframe);
4756 ta = get_ta(wlanhdr);
4757 ra = get_ra(wlanhdr);
4758 is_ra_bmc = IS_MCAST(ra);
4760 if (_rtw_memcmp(adapter_mac_addr(padapter), ta, ETH_ALEN) == _TRUE) {
4761 static systime start_time = 0;
4763 #if 0 /*For debug */
4764 if (IsFrameTypeCtrl(wlanhdr)) {
4765 RTW_INFO("-->Control frame: Y\n");
4766 RTW_INFO("-->pkt_len: %d\n", pattrib->pkt_len);
4767 RTW_INFO("-->Sub Type = 0x%X\n", get_frame_sub_type(wlanhdr));
4770 /* Dump first 40 bytes of header */
4773 for (i = 0; i < 40; i++)
4774 RTW_INFO("%d: %X\n", i, *((u8 *)wlanhdr + i));
4779 if ((start_time == 0) || (rtw_get_passing_time_ms(start_time) > 5000)) {
4780 RTW_PRINT("Warning!!! %s: Confilc mac addr!!\n", __func__);
4781 start_time = rtw_get_current_time();
4783 precvpriv->dbg_rx_conflic_mac_addr_cnt++;
4785 pstapriv = &padapter->stapriv;
4786 psta = rtw_get_stainfo(pstapriv, ta);
4788 pkt_info.station_id = psta->cmn.mac_id;
4791 pkt_info.is_packet_match_bssid = (!IsFrameTypeCtrl(wlanhdr))
4792 && (!pattrib->icv_err) && (!pattrib->crc_err)
4793 && ((!MLME_IS_MESH(padapter) && _rtw_memcmp(get_hdr_bssid(wlanhdr), get_bssid(&padapter->mlmepriv), ETH_ALEN))
4794 || (MLME_IS_MESH(padapter) && psta));
4796 pkt_info.is_to_self = (!pattrib->icv_err) && (!pattrib->crc_err)
4797 && _rtw_memcmp(ra, adapter_mac_addr(padapter), ETH_ALEN);
4799 pkt_info.is_packet_to_self = pkt_info.is_packet_match_bssid
4800 && _rtw_memcmp(ra, adapter_mac_addr(padapter), ETH_ALEN);
4802 pkt_info.is_packet_beacon = pkt_info.is_packet_match_bssid
4803 && (get_frame_sub_type(wlanhdr) == WIFI_BEACON);
4805 if (psta && IsFrameTypeData(wlanhdr)) {
4807 psta->curr_rx_rate_bmc = pattrib->data_rate;
4809 psta->curr_rx_rate = pattrib->data_rate;
4811 pkt_info.data_rate = pattrib->data_rate;
4813 odm_phy_status_query(&pHalData->odmpriv, p_phy_info, pphy_status, &pkt_info);
4815 /* If bw is initial value, get from phy status */
4816 if (pattrib->bw == CHANNEL_WIDTH_MAX)
4817 pattrib->bw = p_phy_info->band_width;
4820 precvframe->u.hdr.psta = NULL;
4821 if (padapter->registrypriv.mp_mode != 1) {
4822 if ((!MLME_IS_MESH(padapter) && pkt_info.is_packet_match_bssid)
4823 || (MLME_IS_MESH(padapter) && psta)) {
4825 precvframe->u.hdr.psta = psta;
4826 rx_process_phy_info(padapter, precvframe);
4828 } else if (pkt_info.is_packet_to_self || pkt_info.is_packet_beacon) {
4830 precvframe->u.hdr.psta = psta;
4831 rx_process_phy_info(padapter, precvframe);
4834 #ifdef CONFIG_MP_INCLUDED
4835 if (padapter->mppriv.brx_filter_beacon == _TRUE) {
4836 if (pkt_info.is_packet_beacon) {
4837 RTW_INFO("in MP Rx is_packet_beacon\n");
4839 precvframe->u.hdr.psta = psta;
4840 rx_process_phy_info(padapter, precvframe);
4846 precvframe->u.hdr.psta = psta;
4847 rx_process_phy_info(padapter, precvframe);
4852 rtw_odm_parse_rx_phy_status_chinfo(precvframe, pphy_status);
4855 * Increase and check if the continual_no_rx_packet of this @param pmlmepriv is larger than MAX_CONTINUAL_NORXPACKET_COUNT
4859 int rtw_inc_and_chk_continual_no_rx_packet(struct sta_info *sta, int tid_index)
4863 int value = ATOMIC_INC_RETURN(&sta->continual_no_rx_packet[tid_index]);
4865 if (value >= MAX_CONTINUAL_NORXPACKET_COUNT)
4872 * Set the continual_no_rx_packet of this @param pmlmepriv to 0
4874 void rtw_reset_continual_no_rx_packet(struct sta_info *sta, int tid_index)
4876 ATOMIC_SET(&sta->continual_no_rx_packet[tid_index], 0);
4879 u8 adapter_allow_bmc_data_rx(_adapter *adapter)
4881 if (check_fwstate(&adapter->mlmepriv, WIFI_MONITOR_STATE | WIFI_MP_STATE) == _TRUE)
4884 if (MLME_IS_AP(adapter))
4887 if (rtw_linked_check(adapter) == _FALSE)
4893 s32 pre_recv_entry(union recv_frame *precvframe, u8 *pphy_status)
4896 u8 *pbuf = precvframe->u.hdr.rx_data;
4897 u8 *pda = get_ra(pbuf);
4898 u8 ra_is_bmc = IS_MCAST(pda);
4899 _adapter *primary_padapter = precvframe->u.hdr.adapter;
4900 #ifdef CONFIG_CONCURRENT_MODE
4901 _adapter *iface = NULL;
4903 #ifdef CONFIG_MP_INCLUDED
4904 if (rtw_mp_mode_check(primary_padapter))
4905 goto bypass_concurrent_hdl;
4908 if (ra_is_bmc == _FALSE) { /*unicast packets*/
4909 iface = rtw_get_iface_by_macddr(primary_padapter , pda);
4910 if (NULL == iface) {
4911 #ifdef CONFIG_RTW_CFGVENDOR_RANDOM_MAC_OUI
4912 if (_rtw_memcmp(pda, adapter_pno_mac_addr(primary_padapter),
4915 RTW_INFO("%s [WARN] Cannot find appropriate adapter - mac_addr : "MAC_FMT"\n", __func__, MAC_ARG(pda));
4918 precvframe->u.hdr.adapter = iface;
4919 } else /* Handle BC/MC Packets */
4920 rtw_mi_buddy_clone_bcmc_packet(primary_padapter, precvframe, pphy_status);
4921 bypass_concurrent_hdl:
4922 #endif /* CONFIG_CONCURRENT_MODE */
4923 if (primary_padapter->registrypriv.mp_mode != 1) {
4924 /* skip unnecessary bmc data frame for primary adapter */
4925 if (ra_is_bmc == _TRUE && GetFrameType(pbuf) == WIFI_DATA_TYPE
4926 && !adapter_allow_bmc_data_rx(precvframe->u.hdr.adapter)
4928 rtw_free_recvframe(precvframe, &precvframe->u.hdr.adapter->recvpriv.free_recv_queue);
4934 rx_query_phy_status(precvframe, pphy_status);
4935 ret = rtw_recv_entry(precvframe);
4941 #ifdef CONFIG_RECV_THREAD_MODE
4942 thread_return rtw_recv_thread(thread_context context)
4944 _adapter *adapter = (_adapter *)context;
4945 struct recv_priv *recvpriv = &adapter->recvpriv;
4947 #ifdef RTW_RECV_THREAD_HIGH_PRIORITY
4948 #ifdef PLATFORM_LINUX
4949 struct sched_param param = { .sched_priority = 1 };
4951 sched_setscheduler(current, SCHED_FIFO, ¶m);
4952 #endif /* PLATFORM_LINUX */
4953 #endif /*RTW_RECV_THREAD_HIGH_PRIORITY*/
4954 thread_enter("RTW_RECV_THREAD");
4956 RTW_INFO(FUNC_ADPT_FMT" enter\n", FUNC_ADPT_ARG(adapter));
4959 err = _rtw_down_sema(&recvpriv->recv_sema);
4961 RTW_ERR(FUNC_ADPT_FMT" down recv_sema fail!\n", FUNC_ADPT_ARG(adapter));
4965 if (RTW_CANNOT_RUN(adapter)) {
4966 RTW_DBG(FUNC_ADPT_FMT "- bDriverStopped(%s) bSurpriseRemoved(%s)\n",
4967 FUNC_ADPT_ARG(adapter),
4968 rtw_is_drv_stopped(adapter) ? "True" : "False",
4969 rtw_is_surprise_removed(adapter) ? "True" : "False");
4973 err = rtw_hal_recv_hdl(adapter);
4975 if (err == RTW_RFRAME_UNAVAIL
4976 || err == RTW_RFRAME_PKT_UNAVAIL
4979 _rtw_up_sema(&recvpriv->recv_sema);
4982 flush_signals_thread();
4984 } while (err != _FAIL);
4988 RTW_INFO(FUNC_ADPT_FMT " Exit\n", FUNC_ADPT_ARG(adapter));
4990 rtw_thread_wait_stop();
4994 #endif /* CONFIG_RECV_THREAD_MODE */
4996 #if DBG_RX_BH_TRACKING
4997 void rx_bh_tk_set_stage(struct recv_priv *recv, u32 s)
4999 recv->rx_bh_stage = s;
5002 void rx_bh_tk_set_buf(struct recv_priv *recv, void *buf, void *data, u32 dlen)
5004 if (recv->rx_bh_cbuf)
5005 recv->rx_bh_lbuf = recv->rx_bh_cbuf;
5006 recv->rx_bh_cbuf = buf;
5008 recv->rx_bh_cbuf_data = data;
5009 recv->rx_bh_cbuf_dlen = dlen;
5010 recv->rx_bh_buf_dq_cnt++;
5012 recv->rx_bh_cbuf_data = NULL;
5013 recv->rx_bh_cbuf_dlen = 0;
5017 void rx_bh_tk_set_buf_pos(struct recv_priv *recv, void *pos)
5019 if (recv->rx_bh_cbuf) {
5020 recv->rx_bh_cbuf_pos = pos - recv->rx_bh_cbuf_data;
5023 recv->rx_bh_cbuf_pos = 0;
5027 void rx_bh_tk_set_frame(struct recv_priv *recv, void *frame)
5029 recv->rx_bh_cframe = frame;
5032 void dump_rx_bh_tk(void *sel, struct recv_priv *recv)
5034 RTW_PRINT_SEL(sel, "[RXBHTK]s:%u, buf_dqc:%u, lbuf:%p, cbuf:%p, dlen:%u, pos:%u, cframe:%p\n"
5036 , recv->rx_bh_buf_dq_cnt
5039 , recv->rx_bh_cbuf_dlen
5040 , recv->rx_bh_cbuf_pos
5041 , recv->rx_bh_cframe
5044 #endif /* DBG_RX_BH_TRACKING */