1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <mlme_osdep.h>
34 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
36 #error "Shall be Linux or Windows, but not both!\n"
43 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
44 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS
);
45 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
48 void _rtw_init_sta_recv_priv(struct sta_recv_priv
*psta_recvpriv
)
54 _rtw_memset((u8
*)psta_recvpriv
, 0, sizeof (struct sta_recv_priv
));
56 _rtw_spinlock_init(&psta_recvpriv
->lock
);
58 //for(i=0; i<MAX_RX_NUMBLKS; i++)
59 // _rtw_init_queue(&psta_recvpriv->blk_strms[i]);
61 _rtw_init_queue(&psta_recvpriv
->defrag_q
);
67 sint
_rtw_init_recv_priv(struct recv_priv
*precvpriv
, _adapter
*padapter
)
71 union recv_frame
*precvframe
;
77 // We don't need to memset padapter->XXX to zero, because adapter is allocated by rtw_zvmalloc().
78 //_rtw_memset((unsigned char *)precvpriv, 0, sizeof (struct recv_priv));
80 _rtw_spinlock_init(&precvpriv
->lock
);
82 _rtw_init_queue(&precvpriv
->free_recv_queue
);
83 _rtw_init_queue(&precvpriv
->recv_pending_queue
);
84 _rtw_init_queue(&precvpriv
->uc_swdec_pending_queue
);
86 precvpriv
->adapter
= padapter
;
88 precvpriv
->free_recvframe_cnt
= NR_RECVFRAME
;
90 rtw_os_recv_resource_init(precvpriv
, padapter
);
92 precvpriv
->pallocated_frame_buf
= rtw_zvmalloc(NR_RECVFRAME
* sizeof(union recv_frame
) + RXFRAME_ALIGN_SZ
);
94 if(precvpriv
->pallocated_frame_buf
==NULL
){
98 //_rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
100 precvpriv
->precv_frame_buf
= (u8
*)N_BYTE_ALIGMENT((SIZE_PTR
)(precvpriv
->pallocated_frame_buf
), RXFRAME_ALIGN_SZ
);
101 //precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ -
102 // ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1));
104 precvframe
= (union recv_frame
*) precvpriv
->precv_frame_buf
;
107 for(i
=0; i
< NR_RECVFRAME
; i
++)
109 _rtw_init_listhead(&(precvframe
->u
.list
));
111 rtw_list_insert_tail(&(precvframe
->u
.list
), &(precvpriv
->free_recv_queue
.queue
));
113 res
= rtw_os_recv_resource_alloc(padapter
, precvframe
);
115 precvframe
->u
.hdr
.adapter
=padapter
;
120 #ifdef CONFIG_USB_HCI
122 precvpriv
->rx_pending_cnt
=1;
124 _rtw_init_sema(&precvpriv
->allrxreturnevt
, 0);
128 res
= rtw_hal_init_recv_priv(padapter
);
130 precvpriv
->recvbuf_skb_alloc_fail_cnt
= 0;
131 precvpriv
->recvbuf_null_cnt
= 0;
132 precvpriv
->read_port_complete_EINPROGRESS_cnt
= 0;
133 precvpriv
->read_port_complete_other_urb_err_cnt
= 0;
135 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
136 #ifdef PLATFORM_LINUX
137 _init_timer(&precvpriv
->signal_stat_timer
, padapter
->pnetdev
, RTW_TIMER_HDL_NAME(signal_stat
), padapter
);
138 #elif defined(PLATFORM_OS_CE) || defined(PLATFORM_WINDOWS)
139 _init_timer(&precvpriv
->signal_stat_timer
, padapter
->hndis_adapter
, RTW_TIMER_HDL_NAME(signal_stat
), padapter
);
142 precvpriv
->signal_stat_sampling_interval
= 1000; //ms
143 //precvpriv->signal_stat_converging_constant = 5000; //ms
145 rtw_set_signal_stat_timer(precvpriv
);
146 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
156 void rtw_mfree_recv_priv_lock(struct recv_priv
*precvpriv
);
157 void rtw_mfree_recv_priv_lock(struct recv_priv
*precvpriv
)
159 _rtw_spinlock_free(&precvpriv
->lock
);
160 #ifdef CONFIG_RECV_THREAD_MODE
161 _rtw_free_sema(&precvpriv
->recv_sema
);
162 _rtw_free_sema(&precvpriv
->terminate_recvthread_sema
);
165 _rtw_spinlock_free(&precvpriv
->free_recv_queue
.lock
);
166 _rtw_spinlock_free(&precvpriv
->recv_pending_queue
.lock
);
168 _rtw_spinlock_free(&precvpriv
->free_recv_buf_queue
.lock
);
170 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
171 _rtw_spinlock_free(&precvpriv
->recv_buf_pending_queue
.lock
);
172 #endif // CONFIG_USE_USB_BUFFER_ALLOC_RX
175 void _rtw_free_recv_priv (struct recv_priv
*precvpriv
)
177 _adapter
*padapter
= precvpriv
->adapter
;
181 rtw_free_uc_swdec_pending_queue(padapter
);
183 rtw_mfree_recv_priv_lock(precvpriv
);
185 rtw_os_recv_resource_free(precvpriv
);
187 if(precvpriv
->pallocated_frame_buf
) {
188 rtw_vmfree(precvpriv
->pallocated_frame_buf
, NR_RECVFRAME
* sizeof(union recv_frame
) + RXFRAME_ALIGN_SZ
);
191 rtw_hal_free_recv_priv(padapter
);
197 union recv_frame
*_rtw_alloc_recvframe (_queue
*pfree_recv_queue
)
200 union recv_frame
*precvframe
;
201 _list
*plist
, *phead
;
203 struct recv_priv
*precvpriv
;
206 if(_rtw_queue_empty(pfree_recv_queue
) == _TRUE
)
212 phead
= get_list_head(pfree_recv_queue
);
214 plist
= get_next(phead
);
216 precvframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
218 rtw_list_delete(&precvframe
->u
.hdr
.list
);
219 padapter
=precvframe
->u
.hdr
.adapter
;
221 precvpriv
=&padapter
->recvpriv
;
222 if(pfree_recv_queue
== &precvpriv
->free_recv_queue
)
223 precvpriv
->free_recvframe_cnt
--;
233 union recv_frame
*rtw_alloc_recvframe (_queue
*pfree_recv_queue
)
236 union recv_frame
*precvframe
;
238 _enter_critical_bh(&pfree_recv_queue
->lock
, &irqL
);
240 precvframe
= _rtw_alloc_recvframe(pfree_recv_queue
);
242 _exit_critical_bh(&pfree_recv_queue
->lock
, &irqL
);
247 void rtw_init_recvframe(union recv_frame
*precvframe
, struct recv_priv
*precvpriv
)
249 /* Perry: This can be removed */
250 _rtw_init_listhead(&precvframe
->u
.hdr
.list
);
252 precvframe
->u
.hdr
.len
=0;
255 int rtw_free_recvframe(union recv_frame
*precvframe
, _queue
*pfree_recv_queue
)
258 _adapter
*padapter
=precvframe
->u
.hdr
.adapter
;
259 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
263 #ifdef CONFIG_CONCURRENT_MODE
264 if(padapter
->adapter_type
> PRIMARY_ADAPTER
)
266 padapter
= padapter
->pbuddy_adapter
;//get primary_padapter
267 precvpriv
= &padapter
->recvpriv
;
268 pfree_recv_queue
= &precvpriv
->free_recv_queue
;
269 precvframe
->u
.hdr
.adapter
= padapter
;
274 #ifdef PLATFORM_WINDOWS
275 rtw_os_read_port(padapter
, precvframe
->u
.hdr
.precvbuf
);
278 #if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
280 if(precvframe
->u
.hdr
.pkt
)
282 #ifdef CONFIG_BSD_RX_USE_MBUF
283 m_freem(precvframe
->u
.hdr
.pkt
);
284 #else // CONFIG_BSD_RX_USE_MBUF
285 rtw_skb_free(precvframe
->u
.hdr
.pkt
);//free skb by driver
286 #endif // CONFIG_BSD_RX_USE_MBUF
287 precvframe
->u
.hdr
.pkt
= NULL
;
290 #endif //defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
292 _enter_critical_bh(&pfree_recv_queue
->lock
, &irqL
);
294 rtw_list_delete(&(precvframe
->u
.hdr
.list
));
296 rtw_list_insert_tail(&(precvframe
->u
.hdr
.list
), get_list_head(pfree_recv_queue
));
299 if(pfree_recv_queue
== &precvpriv
->free_recv_queue
)
300 precvpriv
->free_recvframe_cnt
++;
303 _exit_critical_bh(&pfree_recv_queue
->lock
, &irqL
);
314 sint
_rtw_enqueue_recvframe(union recv_frame
*precvframe
, _queue
*queue
)
317 _adapter
*padapter
=precvframe
->u
.hdr
.adapter
;
318 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
322 //_rtw_init_listhead(&(precvframe->u.hdr.list));
323 rtw_list_delete(&(precvframe
->u
.hdr
.list
));
326 rtw_list_insert_tail(&(precvframe
->u
.hdr
.list
), get_list_head(queue
));
328 if (padapter
!= NULL
) {
329 if (queue
== &precvpriv
->free_recv_queue
)
330 precvpriv
->free_recvframe_cnt
++;
338 sint
rtw_enqueue_recvframe(union recv_frame
*precvframe
, _queue
*queue
)
343 //_spinlock(&pfree_recv_queue->lock);
344 _enter_critical_bh(&queue
->lock
, &irqL
);
345 ret
= _rtw_enqueue_recvframe(precvframe
, queue
);
346 //_rtw_spinunlock(&pfree_recv_queue->lock);
347 _exit_critical_bh(&queue
->lock
, &irqL
);
353 sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
355 return rtw_free_recvframe(precvframe, queue);
363 caller : defrag ; recvframe_chk_defrag in recv_thread (passive)
364 pframequeue: defrag_queue : will be accessed in recv_thread (passive)
366 using spinlock to protect
370 void rtw_free_recvframe_queue(_queue
*pframequeue
, _queue
*pfree_recv_queue
)
372 union recv_frame
*precvframe
;
373 _list
*plist
, *phead
;
376 _rtw_spinlock(&pframequeue
->lock
);
378 phead
= get_list_head(pframequeue
);
379 plist
= get_next(phead
);
381 while(rtw_end_of_queue_search(phead
, plist
) == _FALSE
)
383 precvframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
385 plist
= get_next(plist
);
387 //rtw_list_delete(&precvframe->u.hdr.list); // will do this in rtw_free_recvframe()
389 rtw_free_recvframe(precvframe
, pfree_recv_queue
);
392 _rtw_spinunlock(&pframequeue
->lock
);
398 u32
rtw_free_uc_swdec_pending_queue(_adapter
*adapter
)
401 union recv_frame
*pending_frame
;
402 while((pending_frame
=rtw_alloc_recvframe(&adapter
->recvpriv
.uc_swdec_pending_queue
))) {
403 rtw_free_recvframe(pending_frame
, &adapter
->recvpriv
.free_recv_queue
);
404 DBG_871X("%s: dequeue uc_swdec_pending_queue\n", __func__
);
412 sint
rtw_enqueue_recvbuf_to_head(struct recv_buf
*precvbuf
, _queue
*queue
)
416 _enter_critical(&queue
->lock
, &irqL
);
418 rtw_list_delete(&precvbuf
->list
);
419 rtw_list_insert_head(&precvbuf
->list
, get_list_head(queue
));
421 _exit_critical(&queue
->lock
, &irqL
);
426 sint
rtw_enqueue_recvbuf(struct recv_buf
*precvbuf
, _queue
*queue
)
430 _enter_critical(&queue
->lock
, &irqL
);
432 rtw_list_delete(&precvbuf
->list
);
434 rtw_list_insert_tail(&precvbuf
->list
, get_list_head(queue
));
436 _exit_critical(&queue
->lock
, &irqL
);
443 struct recv_buf
*rtw_dequeue_recvbuf (_queue
*queue
)
446 struct recv_buf
*precvbuf
;
447 _list
*plist
, *phead
;
449 _enter_critical(&queue
->lock
, &irqL
);
451 if(_rtw_queue_empty(queue
) == _TRUE
)
457 phead
= get_list_head(queue
);
459 plist
= get_next(phead
);
461 precvbuf
= LIST_CONTAINOR(plist
, struct recv_buf
, list
);
463 rtw_list_delete(&precvbuf
->list
);
467 _exit_critical(&queue
->lock
, &irqL
);
474 sint
recvframe_chkmic(_adapter
*adapter
, union recv_frame
*precvframe
);
475 sint
recvframe_chkmic(_adapter
*adapter
, union recv_frame
*precvframe
){
480 u8 bmic_err
=_FALSE
,brpt_micerror
= _TRUE
;
481 u8
*pframe
, *payload
,*pframemic
;
483 //u8 *iv,rxdata_key_idx=0;
484 struct sta_info
*stainfo
;
485 struct rx_pkt_attrib
*prxattrib
=&precvframe
->u
.hdr
.attrib
;
486 struct security_priv
*psecuritypriv
=&adapter
->securitypriv
;
488 struct mlme_ext_priv
*pmlmeext
= &adapter
->mlmeextpriv
;
489 struct mlme_ext_info
*pmlmeinfo
= &(pmlmeext
->mlmext_info
);
492 stainfo
=rtw_get_stainfo(&adapter
->stapriv
,&prxattrib
->ta
[0]);
494 if(prxattrib
->encrypt
==_TKIP_
)
496 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n recvframe_chkmic:prxattrib->encrypt ==_TKIP_\n"));
497 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n recvframe_chkmic:da=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
498 prxattrib
->ra
[0],prxattrib
->ra
[1],prxattrib
->ra
[2],prxattrib
->ra
[3],prxattrib
->ra
[4],prxattrib
->ra
[5]));
503 if(IS_MCAST(prxattrib
->ra
))
505 //mickey=&psecuritypriv->dot118021XGrprxmickey.skey[0];
506 //iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen;
507 //rxdata_key_idx =( ((iv[3])>>6)&0x3) ;
508 mickey
=&psecuritypriv
->dot118021XGrprxmickey
[prxattrib
->key_index
].skey
[0];
510 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n recvframe_chkmic: bcmc key \n"));
511 //DBG_871X("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d),pmlmeinfo->key_index(%d) ,recv key_id(%d)\n",
512 // psecuritypriv->dot118021XGrpKeyid,pmlmeinfo->key_index,rxdata_key_idx);
514 if(psecuritypriv
->binstallGrpkey
==_FALSE
)
517 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"));
518 DBG_871X("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
523 mickey
=&stainfo
->dot11tkiprxmickey
.skey
[0];
524 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n recvframe_chkmic: unicast key \n"));
527 datalen
=precvframe
->u
.hdr
.len
-prxattrib
->hdrlen
-prxattrib
->iv_len
-prxattrib
->icv_len
-8;//icv_len included the mic code
528 pframe
=precvframe
->u
.hdr
.rx_data
;
529 payload
=pframe
+prxattrib
->hdrlen
+prxattrib
->iv_len
;
531 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n prxattrib->iv_len=%d prxattrib->icv_len=%d\n",prxattrib
->iv_len
,prxattrib
->icv_len
));
533 //rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data
535 rtw_seccalctkipmic(mickey
,pframe
,payload
, datalen
,&miccode
[0],(unsigned char)prxattrib
->priority
); //care the length of the data
537 pframemic
=payload
+datalen
;
542 if(miccode
[i
] != *(pframemic
+i
)){
543 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ",i
,miccode
[i
],i
,*(pframemic
+i
)));
551 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n *(pframemic-8)-*(pframemic-1)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
552 *(pframemic
-8),*(pframemic
-7),*(pframemic
-6),*(pframemic
-5),*(pframemic
-4),*(pframemic
-3),*(pframemic
-2),*(pframemic
-1)));
553 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n *(pframemic-16)-*(pframemic-9)=0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
554 *(pframemic
-16),*(pframemic
-15),*(pframemic
-14),*(pframemic
-13),*(pframemic
-12),*(pframemic
-11),*(pframemic
-10),*(pframemic
-9)));
558 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n ======demp packet (len=%d)======\n",precvframe
->u
.hdr
.len
));
559 for(i
=0;i
<precvframe
->u
.hdr
.len
;i
=i
+8){
560 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x",
561 *(precvframe
->u
.hdr
.rx_data
+i
),*(precvframe
->u
.hdr
.rx_data
+i
+1),
562 *(precvframe
->u
.hdr
.rx_data
+i
+2),*(precvframe
->u
.hdr
.rx_data
+i
+3),
563 *(precvframe
->u
.hdr
.rx_data
+i
+4),*(precvframe
->u
.hdr
.rx_data
+i
+5),
564 *(precvframe
->u
.hdr
.rx_data
+i
+6),*(precvframe
->u
.hdr
.rx_data
+i
+7)));
566 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n ======demp packet end [len=%d]======\n",precvframe
->u
.hdr
.len
));
567 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("\n hrdlen=%d, \n",prxattrib
->hdrlen
));
570 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("ra=0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey=%d ",
571 prxattrib
->ra
[0],prxattrib
->ra
[1],prxattrib
->ra
[2],
572 prxattrib
->ra
[3],prxattrib
->ra
[4],prxattrib
->ra
[5],psecuritypriv
->binstallGrpkey
));
574 // double check key_index for some timing issue ,
575 // cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue
576 if((IS_MCAST(prxattrib
->ra
)==_TRUE
) && (prxattrib
->key_index
!= pmlmeinfo
->key_index
))
577 brpt_micerror
= _FALSE
;
579 if(brpt_micerror
== _TRUE
)
581 rtw_handle_tkip_mic_err(adapter
,(u8
)IS_MCAST(prxattrib
->ra
));
582 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,(" mic error :prxattrib->bdecrypted=%d \n", brpt_micerror
));
583 DBG_871X(" mic error :brpt_micerror=%d\n", brpt_micerror
);
591 if((psecuritypriv
->bcheck_grpkey
==_FALSE
)&&(IS_MCAST(prxattrib
->ra
)==_TRUE
)){
592 psecuritypriv
->bcheck_grpkey
=_TRUE
;
593 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("psecuritypriv->bcheck_grpkey =_TRUE"));
600 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n"));
603 recvframe_pull_tail(precvframe
, 8);
615 //decrypt and set the ivlen,icvlen of the recv_frame
616 union recv_frame
* decryptor(_adapter
*padapter
,union recv_frame
*precv_frame
);
617 union recv_frame
* decryptor(_adapter
*padapter
,union recv_frame
*precv_frame
)
620 struct rx_pkt_attrib
*prxattrib
= &precv_frame
->u
.hdr
.attrib
;
621 struct security_priv
*psecuritypriv
=&padapter
->securitypriv
;
622 union recv_frame
*return_packet
=precv_frame
;
626 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("prxstat->decrypted=%x prxattrib->encrypt = 0x%03x\n",prxattrib
->bdecrypted
,prxattrib
->encrypt
));
628 if(prxattrib
->encrypt
>0)
630 u8
*iv
= precv_frame
->u
.hdr
.rx_data
+prxattrib
->hdrlen
;
631 prxattrib
->key_index
= ( ((iv
[3])>>6)&0x3) ;
633 if(prxattrib
->key_index
> WEP_KEYS
)
635 DBG_871X("prxattrib->key_index(%d) > WEP_KEYS \n", prxattrib
->key_index
);
637 switch(prxattrib
->encrypt
){
640 prxattrib
->key_index
= psecuritypriv
->dot11PrivacyKeyIndex
;
645 prxattrib
->key_index
= psecuritypriv
->dot118021XGrpKeyid
;
651 if((prxattrib
->encrypt
>0) && ((prxattrib
->bdecrypted
==0) ||(psecuritypriv
->sw_decrypt
==_TRUE
)))
654 #ifdef CONFIG_CONCURRENT_MODE
655 if(!IS_MCAST(prxattrib
->ra
))//bc/mc packets use sw decryption for concurrent mode
657 psecuritypriv
->hw_decrypted
=_FALSE
;
659 #ifdef DBG_RX_DECRYPTOR
660 DBG_871X("prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n"
661 , prxattrib
->bdecrypted
,prxattrib
->encrypt
, psecuritypriv
->hw_decrypted
);
664 switch(prxattrib
->encrypt
){
667 rtw_wep_decrypt(padapter
, (u8
*)precv_frame
);
670 res
= rtw_tkip_decrypt(padapter
, (u8
*)precv_frame
);
673 res
= rtw_aes_decrypt(padapter
, (u8
* )precv_frame
);
679 else if(prxattrib
->bdecrypted
==1
680 && prxattrib
->encrypt
>0
681 && (psecuritypriv
->busetkipkey
==1 || prxattrib
->encrypt
!=_TKIP_
)
685 if((prxstat
->icv
==1)&&(prxattrib
->encrypt
!=_AES_
))
687 psecuritypriv
->hw_decrypted
=_FALSE
;
689 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("psecuritypriv->hw_decrypted=_FALSE"));
691 rtw_free_recvframe(precv_frame
, &padapter
->recvpriv
.free_recv_queue
);
699 psecuritypriv
->hw_decrypted
=_TRUE
;
700 #ifdef DBG_RX_DECRYPTOR
701 DBG_871X("prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n"
702 , prxattrib
->bdecrypted
,prxattrib
->encrypt
, psecuritypriv
->hw_decrypted
);
708 #ifdef DBG_RX_DECRYPTOR
709 DBG_871X("prxstat->bdecrypted:%d, prxattrib->encrypt:%d, psecuritypriv->hw_decrypted:%d\n"
710 , prxattrib
->bdecrypted
,prxattrib
->encrypt
, psecuritypriv
->hw_decrypted
);
716 rtw_free_recvframe(return_packet
,&padapter
->recvpriv
.free_recv_queue
);
717 return_packet
= NULL
;
720 //recvframe_chkmic(adapter, precv_frame); //move to recvframme_defrag function
724 return return_packet
;
727 //###set the security information in the recv_frame
728 union recv_frame
* portctrl(_adapter
*adapter
,union recv_frame
* precv_frame
);
729 union recv_frame
* portctrl(_adapter
*adapter
,union recv_frame
* precv_frame
)
733 struct recv_frame_hdr
*pfhdr
;
734 struct sta_info
* psta
;
735 struct sta_priv
*pstapriv
;
736 union recv_frame
* prtnframe
;
738 u16 eapol_type
= 0x888e;//for Funia BD's WPA issue
739 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
743 pstapriv
= &adapter
->stapriv
;
744 ptr
= get_recvframe_data(precv_frame
);
745 pfhdr
= &precv_frame
->u
.hdr
;
746 psta_addr
= pfhdr
->attrib
.ta
;
747 psta
= rtw_get_stainfo(pstapriv
, psta_addr
);
749 auth_alg
= adapter
->securitypriv
.dot11AuthAlgrthm
;
751 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("########portctrl:adapter->securitypriv.dot11AuthAlgrthm= 0x%d\n",adapter
->securitypriv
.dot11AuthAlgrthm
));
755 if ((psta
!=NULL
) && (psta
->ieee8021x_blocked
))
758 //only accept EAPOL frame
759 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("########portctrl:psta->ieee8021x_blocked==1\n"));
761 prtnframe
=precv_frame
;
764 ptr
=ptr
+pfhdr
->attrib
.hdrlen
+pfhdr
->attrib
.iv_len
+LLC_HEADER_SIZE
;
765 _rtw_memcpy(ðer_type
,ptr
, 2);
766 ether_type
= ntohs((unsigned short )ether_type
);
768 if (ether_type
== eapol_type
) {
769 prtnframe
=precv_frame
;
773 rtw_free_recvframe(precv_frame
, &adapter
->recvpriv
.free_recv_queue
);
780 //check decryption status, and decrypt the frame if needed
781 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("########portctrl:psta->ieee8021x_blocked==0\n"));
782 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("portctrl:precv_frame->hdr.attrib.privacy=%x\n",precv_frame
->u
.hdr
.attrib
.privacy
));
784 if(pattrib
->bdecrypted
==0)
785 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("portctrl:prxstat->decrypted=%x\n", pattrib
->bdecrypted
));
787 prtnframe
=precv_frame
;
788 //check is the EAPOL frame or not (Rekey)
789 if(ether_type
== eapol_type
){
791 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("########portctrl:ether_type == 0x888e\n"));
794 prtnframe
=precv_frame
;
797 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("########portctrl:ether_type = 0x%.4x\n",ether_type
));
803 prtnframe
=precv_frame
;
812 sint
recv_decache(union recv_frame
*precv_frame
, u8 bretry
, struct stainfo_rxcache
*prxcache
);
813 sint
recv_decache(union recv_frame
*precv_frame
, u8 bretry
, struct stainfo_rxcache
*prxcache
)
815 sint tid
= precv_frame
->u
.hdr
.attrib
.priority
;
817 u16 seq_ctrl
= ( (precv_frame
->u
.hdr
.attrib
.seq_num
&0xffff) << 4) |
818 (precv_frame
->u
.hdr
.attrib
.frag_num
& 0xf);
824 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
, ("recv_decache, (tid>15)! seq_ctrl=0x%x, tid=0x%x\n", seq_ctrl
, tid
));
831 if(seq_ctrl
== prxcache
->tid_rxseq
[tid
])
833 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
, ("recv_decache, seq_ctrl=0x%x, tid=0x%x, tid_rxseq=0x%x\n", seq_ctrl
, tid
, prxcache
->tid_rxseq
[tid
]));
839 prxcache
->tid_rxseq
[tid
] = seq_ctrl
;
847 void process_pwrbit_data(_adapter
*padapter
, union recv_frame
*precv_frame
);
848 void process_pwrbit_data(_adapter
*padapter
, union recv_frame
*precv_frame
)
850 #ifdef CONFIG_AP_MODE
851 unsigned char pwrbit
;
852 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
853 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
854 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
855 struct sta_info
*psta
=NULL
;
857 psta
= rtw_get_stainfo(pstapriv
, pattrib
->src
);
859 pwrbit
= GetPwrMgt(ptr
);
865 if(!(psta
->state
& WIFI_SLEEP_STATE
))
867 //psta->state |= WIFI_SLEEP_STATE;
868 //pstapriv->sta_dz_bitmap |= BIT(psta->aid);
870 stop_sta_xmit(padapter
, psta
);
872 //DBG_871X("to sleep, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap);
877 if(psta
->state
& WIFI_SLEEP_STATE
)
879 //psta->state ^= WIFI_SLEEP_STATE;
880 //pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
882 wakeup_sta_to_xmit(padapter
, psta
);
884 //DBG_871X("to wakeup, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap);
893 void process_wmmps_data(_adapter
*padapter
, union recv_frame
*precv_frame
);
894 void process_wmmps_data(_adapter
*padapter
, union recv_frame
*precv_frame
)
896 #ifdef CONFIG_AP_MODE
897 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
898 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
899 struct sta_info
*psta
=NULL
;
901 psta
= rtw_get_stainfo(pstapriv
, pattrib
->src
);
906 if( !(psta
->tdls_sta_state
& TDLS_LINKED_STATE
) )
910 if(!psta
->qos_option
)
913 if(!(psta
->qos_info
&0xf))
920 if(psta
->state
&WIFI_SLEEP_STATE
)
924 switch(pattrib
->priority
)
928 wmmps_ac
= psta
->uapsd_bk
&BIT(1);
932 wmmps_ac
= psta
->uapsd_vi
&BIT(1);
936 wmmps_ac
= psta
->uapsd_vo
&BIT(1);
941 wmmps_ac
= psta
->uapsd_be
&BIT(1);
947 if(psta
->sleepq_ac_len
>0)
949 //process received triggered frame
950 xmit_delivery_enabled_frames(padapter
, psta
);
954 //issue one qos null frame with More data bit = 0 and the EOSP bit set (=1)
955 issue_qos_nulldata(padapter
, psta
->hwaddr
, (u16
)pattrib
->priority
, 0, 0);
967 sint
OnTDLS(_adapter
*adapter
, union recv_frame
*precv_frame
)
969 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
971 u8
*paction
= get_recvframe_data(precv_frame
);
972 u8 category_field
= 1;
974 u8 WFA_OUI
[3] = { 0x50, 0x6f, 0x9a };
976 struct tdls_info
*ptdlsinfo
= &(adapter
->tdlsinfo
);
978 //point to action field
979 paction
+=pattrib
->hdrlen
986 if(ptdlsinfo
->enable
== 0)
988 DBG_871X("recv tdls frame, "
989 "but tdls haven't enabled\n");
995 case TDLS_SETUP_REQUEST
:
996 DBG_871X("recv tdls setup request frame\n");
997 ret
=On_TDLS_Setup_Req(adapter
, precv_frame
);
999 case TDLS_SETUP_RESPONSE
:
1000 DBG_871X("recv tdls setup response frame\n");
1001 ret
=On_TDLS_Setup_Rsp(adapter
, precv_frame
);
1003 case TDLS_SETUP_CONFIRM
:
1004 DBG_871X("recv tdls setup confirm frame\n");
1005 ret
=On_TDLS_Setup_Cfm(adapter
, precv_frame
);
1008 DBG_871X("recv tdls teardown, free sta_info\n");
1009 ret
=On_TDLS_Teardown(adapter
, precv_frame
);
1011 case TDLS_DISCOVERY_REQUEST
:
1012 DBG_871X("recv tdls discovery request frame\n");
1013 ret
=On_TDLS_Dis_Req(adapter
, precv_frame
);
1015 case TDLS_PEER_TRAFFIC_RESPONSE
:
1016 DBG_871X("recv tdls peer traffic response frame\n");
1017 ret
=On_TDLS_Peer_Traffic_Rsp(adapter
, precv_frame
);
1019 case TDLS_CHANNEL_SWITCH_REQUEST
:
1020 DBG_871X("recv tdls channel switch request frame\n");
1021 ret
=On_TDLS_Ch_Switch_Req(adapter
, precv_frame
);
1023 case TDLS_CHANNEL_SWITCH_RESPONSE
:
1024 DBG_871X("recv tdls channel switch response frame\n");
1025 ret
=On_TDLS_Ch_Switch_Rsp(adapter
, precv_frame
);
1028 case 0x50: //First byte of WFA OUI
1029 if( _rtw_memcmp(WFA_OUI
, (paction
), 3) )
1031 if( *(paction
+ 3) == 0x04) //Probe request frame
1033 //WFDTDLS: for sigma test, do not setup direct link automatically
1034 ptdlsinfo
->dev_discovered
= 1;
1035 DBG_871X("recv tunneled probe request frame\n");
1036 issue_tunneled_probe_rsp(adapter
, precv_frame
);
1038 if( *(paction
+ 3) == 0x05) //Probe response frame
1040 //WFDTDLS: for sigma test, do not setup direct link automatically
1041 ptdlsinfo
->dev_discovered
= 1;
1042 DBG_871X("recv tunneled probe response frame\n");
1048 DBG_871X("receive TDLS frame but not supported\n");
1057 #endif //CONFIG_TDLS
1059 void count_rx_stats(_adapter
*padapter
, union recv_frame
*prframe
, struct sta_info
*sta
);
1060 void count_rx_stats(_adapter
*padapter
, union recv_frame
*prframe
, struct sta_info
*sta
)
1063 struct sta_info
*psta
= NULL
;
1064 struct stainfo_stats
*pstats
= NULL
;
1065 struct rx_pkt_attrib
*pattrib
= & prframe
->u
.hdr
.attrib
;
1066 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
1068 sz
= get_recvframe_len(prframe
);
1069 precvpriv
->rx_bytes
+= sz
;
1071 padapter
->mlmepriv
.LinkDetectInfo
.NumRxOkInPeriod
++;
1073 if( (!MacAddr_isBcst(pattrib
->dst
)) && (!IS_MCAST(pattrib
->dst
))){
1074 padapter
->mlmepriv
.LinkDetectInfo
.NumRxUnicastOkInPeriod
++;
1080 psta
= prframe
->u
.hdr
.psta
;
1084 pstats
= &psta
->sta_stats
;
1086 pstats
->rx_data_pkts
++;
1087 pstats
->rx_bytes
+= sz
;
1092 sint
sta2sta_data_frame(
1094 union recv_frame
*precv_frame
,
1095 struct sta_info
**psta
1097 sint
sta2sta_data_frame(
1099 union recv_frame
*precv_frame
,
1100 struct sta_info
**psta
1103 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
1104 sint ret
= _SUCCESS
;
1105 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
1106 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1107 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1108 u8
*mybssid
= get_bssid(pmlmepriv
);
1109 u8
*myhwaddr
= myid(&adapter
->eeprompriv
);
1110 u8
* sta_addr
= NULL
;
1111 sint bmcast
= IS_MCAST(pattrib
->dst
);
1114 struct tdls_info
*ptdlsinfo
= &adapter
->tdlsinfo
;
1115 struct sta_info
*ptdls_sta
=NULL
;
1116 u8
*psnap_type
=ptr
+pattrib
->hdrlen
+ pattrib
->iv_len
+SNAP_SIZE
;
1117 u8
*pframe_body
= psnap_type
+ ETH_TYPE_LEN
+ PAYLOAD_TYPE_LEN
;
1118 #endif //CONFIG_TDLS
1122 if ((check_fwstate(pmlmepriv
, WIFI_ADHOC_STATE
) == _TRUE
) ||
1123 (check_fwstate(pmlmepriv
, WIFI_ADHOC_MASTER_STATE
) == _TRUE
))
1126 // filter packets that SA is myself or multicast or broadcast
1127 if (_rtw_memcmp(myhwaddr
, pattrib
->src
, ETH_ALEN
)){
1128 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,(" SA==myself \n"));
1133 if( (!_rtw_memcmp(myhwaddr
, pattrib
->dst
, ETH_ALEN
)) && (!bmcast
) ){
1138 if( _rtw_memcmp(pattrib
->bssid
, "\x0\x0\x0\x0\x0\x0", ETH_ALEN
) ||
1139 _rtw_memcmp(mybssid
, "\x0\x0\x0\x0\x0\x0", ETH_ALEN
) ||
1140 (!_rtw_memcmp(pattrib
->bssid
, mybssid
, ETH_ALEN
)) ) {
1145 sta_addr
= pattrib
->src
;
1148 else if(check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == _TRUE
)
1151 //direct link data transfer
1152 if(ptdlsinfo
->setup_state
== TDLS_LINKED_STATE
){
1153 ptdls_sta
= rtw_get_stainfo(pstapriv
, pattrib
->src
);
1159 else if(ptdls_sta
->tdls_sta_state
&TDLS_LINKED_STATE
)
1161 //drop QoS-SubType Data, including QoS NULL, excluding QoS-Data
1162 if( (GetFrameSubType(ptr
) & WIFI_QOS_DATA_TYPE
)== WIFI_QOS_DATA_TYPE
)
1164 if(GetFrameSubType(ptr
)&(BIT(4)|BIT(5)|BIT(6)))
1166 DBG_871X("drop QoS-Sybtype Data\n");
1171 // filter packets that SA is myself or multicast or broadcast
1172 if (_rtw_memcmp(myhwaddr
, pattrib
->src
, ETH_ALEN
)){
1176 // da should be for me
1177 if((!_rtw_memcmp(myhwaddr
, pattrib
->dst
, ETH_ALEN
))&& (!bmcast
))
1183 if( _rtw_memcmp(pattrib
->bssid
, "\x0\x0\x0\x0\x0\x0", ETH_ALEN
) ||
1184 _rtw_memcmp(mybssid
, "\x0\x0\x0\x0\x0\x0", ETH_ALEN
) ||
1185 (!_rtw_memcmp(pattrib
->bssid
, mybssid
, ETH_ALEN
)) )
1191 //process UAPSD tdls sta
1192 process_pwrbit_data(adapter
, precv_frame
);
1194 // if NULL-frame, check pwrbit
1195 if ((GetFrameSubType(ptr
)) == WIFI_DATA_NULL
)
1197 //NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA
1200 DBG_871X("TDLS: recv peer null frame with pwr bit 1\n");
1201 ptdls_sta
->tdls_sta_state
|=TDLS_PEER_SLEEP_STATE
;
1203 // it would be triggered when we are off channel and receiving NULL DATA
1204 // we can confirm that peer STA is at off channel
1205 else if(ptdls_sta
->tdls_sta_state
&TDLS_CH_SWITCH_ON_STATE
)
1207 if((ptdls_sta
->tdls_sta_state
& TDLS_PEER_AT_OFF_STATE
) != TDLS_PEER_AT_OFF_STATE
)
1209 issue_nulldata_to_TDLS_peer_STA(adapter
, ptdls_sta
, 0);
1210 ptdls_sta
->tdls_sta_state
|= TDLS_PEER_AT_OFF_STATE
;
1211 On_TDLS_Peer_Traffic_Rsp(adapter
, precv_frame
);
1218 //receive some of all TDLS management frames, process it at ON_TDLS
1219 if((_rtw_memcmp(psnap_type
, SNAP_ETH_TYPE_TDLS
, 2))){
1220 ret
= OnTDLS(adapter
, precv_frame
);
1226 sta_addr
= pattrib
->src
;
1230 #endif //CONFIG_TDLS
1232 // For Station mode, sa and bssid should always be BSSID, and DA is my mac-address
1233 if(!_rtw_memcmp(pattrib
->bssid
, pattrib
->src
, ETH_ALEN
) )
1235 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("bssid != TA under STATION_MODE; drop pkt\n"));
1240 sta_addr
= pattrib
->bssid
;
1243 else if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
1247 // For AP mode, if DA == MCAST, then BSSID should be also MCAST
1248 if (!IS_MCAST(pattrib
->bssid
)){
1253 else // not mc-frame
1255 // For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID
1256 if(!_rtw_memcmp(pattrib
->bssid
, pattrib
->dst
, ETH_ALEN
)) {
1261 sta_addr
= pattrib
->src
;
1265 else if(check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
)
1267 _rtw_memcpy(pattrib
->dst
, GetAddr1Ptr(ptr
), ETH_ALEN
);
1268 _rtw_memcpy(pattrib
->src
, GetAddr2Ptr(ptr
), ETH_ALEN
);
1269 _rtw_memcpy(pattrib
->bssid
, GetAddr3Ptr(ptr
), ETH_ALEN
);
1270 _rtw_memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
1271 _rtw_memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
1283 *psta
= rtw_get_bcmc_stainfo(adapter
);
1285 *psta
= rtw_get_stainfo(pstapriv
, sta_addr
); // get ap_info
1288 if(ptdls_sta
!= NULL
)
1290 #endif //CONFIG_TDLS
1293 if (*psta
== NULL
) {
1294 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("can't get psta under sta2sta_data_frame ; drop pkt\n"));
1295 #ifdef CONFIG_MP_INCLUDED
1296 if(check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
)
1297 adapter
->mppriv
.rx_pktloss
++;
1309 sint
ap2sta_data_frame(
1311 union recv_frame
*precv_frame
,
1312 struct sta_info
**psta
);
1313 sint
ap2sta_data_frame(
1315 union recv_frame
*precv_frame
,
1316 struct sta_info
**psta
)
1318 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
1319 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
1320 sint ret
= _SUCCESS
;
1321 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1322 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1323 u8
*mybssid
= get_bssid(pmlmepriv
);
1324 u8
*myhwaddr
= myid(&adapter
->eeprompriv
);
1325 sint bmcast
= IS_MCAST(pattrib
->dst
);
1329 if ((check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) == _TRUE
)
1330 && (check_fwstate(pmlmepriv
, _FW_LINKED
) == _TRUE
1331 || check_fwstate(pmlmepriv
, _FW_UNDER_LINKING
) == _TRUE
)
1335 // filter packets that SA is myself or multicast or broadcast
1336 if (_rtw_memcmp(myhwaddr
, pattrib
->src
, ETH_ALEN
)){
1337 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,(" SA==myself \n"));
1338 #ifdef DBG_RX_DROP_FRAME
1339 DBG_871X("DBG_RX_DROP_FRAME %s SA=%x:%x:%x:%x:%x:%x, myhwaddr= %x:%x:%x:%x:%x:%x\n", __FUNCTION__
,
1340 pattrib
->src
[0], pattrib
->src
[1], pattrib
->src
[2],
1341 pattrib
->src
[3], pattrib
->src
[4], pattrib
->src
[5],
1342 *(myhwaddr
), *(myhwaddr
+1), *(myhwaddr
+2),
1343 *(myhwaddr
+3), *(myhwaddr
+4), *(myhwaddr
+5));
1349 // da should be for me
1350 if((!_rtw_memcmp(myhwaddr
, pattrib
->dst
, ETH_ALEN
))&& (!bmcast
))
1352 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,
1353 (" ap2sta_data_frame: compare DA fail; DA="MAC_FMT
"\n", MAC_ARG(pattrib
->dst
)));
1354 #ifdef DBG_RX_DROP_FRAME
1355 DBG_871X("DBG_RX_DROP_FRAME %s DA="MAC_FMT
"\n", __func__
, MAC_ARG(pattrib
->dst
));
1363 if( _rtw_memcmp(pattrib
->bssid
, "\x0\x0\x0\x0\x0\x0", ETH_ALEN
) ||
1364 _rtw_memcmp(mybssid
, "\x0\x0\x0\x0\x0\x0", ETH_ALEN
) ||
1365 (!_rtw_memcmp(pattrib
->bssid
, mybssid
, ETH_ALEN
)) )
1367 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,
1368 (" ap2sta_data_frame: compare BSSID fail ; BSSID="MAC_FMT
"\n", MAC_ARG(pattrib
->bssid
)));
1369 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("mybssid="MAC_FMT
"\n", MAC_ARG(mybssid
)));
1370 #ifdef DBG_RX_DROP_FRAME
1371 DBG_871X("DBG_RX_DROP_FRAME %s BSSID="MAC_FMT
", mybssid="MAC_FMT
"\n",
1372 __FUNCTION__
, MAC_ARG(pattrib
->bssid
), MAC_ARG(mybssid
));
1373 DBG_871X( "this adapter = %d, buddy adapter = %d\n", adapter
->adapter_type
, adapter
->pbuddy_adapter
->adapter_type
);
1378 DBG_871X("issue_deauth to the nonassociated ap=" MAC_FMT
" for the reason(7)\n", MAC_ARG(pattrib
->bssid
));
1379 issue_deauth(adapter
, pattrib
->bssid
, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1387 *psta
= rtw_get_bcmc_stainfo(adapter
);
1389 *psta
= rtw_get_stainfo(pstapriv
, pattrib
->bssid
); // get ap_info
1391 if (*psta
== NULL
) {
1392 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("ap2sta: can't get psta under STATION_MODE ; drop pkt\n"));
1393 #ifdef DBG_RX_DROP_FRAME
1394 DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __FUNCTION__
);
1400 if ((GetFrameSubType(ptr
) & WIFI_QOS_DATA_TYPE
) == WIFI_QOS_DATA_TYPE
) {
1403 if (GetFrameSubType(ptr
) & BIT(6)) {
1404 /* No data, will not indicate to upper layer, temporily count it here */
1405 count_rx_stats(adapter
, precv_frame
, *psta
);
1406 ret
= RTW_RX_HANDLED
;
1411 else if ((check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
) &&
1412 (check_fwstate(pmlmepriv
, _FW_LINKED
) == _TRUE
) )
1414 _rtw_memcpy(pattrib
->dst
, GetAddr1Ptr(ptr
), ETH_ALEN
);
1415 _rtw_memcpy(pattrib
->src
, GetAddr2Ptr(ptr
), ETH_ALEN
);
1416 _rtw_memcpy(pattrib
->bssid
, GetAddr3Ptr(ptr
), ETH_ALEN
);
1417 _rtw_memcpy(pattrib
->ra
, pattrib
->dst
, ETH_ALEN
);
1418 _rtw_memcpy(pattrib
->ta
, pattrib
->src
, ETH_ALEN
);
1421 _rtw_memcpy(pattrib
->bssid
, mybssid
, ETH_ALEN
);
1424 *psta
= rtw_get_stainfo(pstapriv
, pattrib
->bssid
); // get sta_info
1425 if (*psta
== NULL
) {
1426 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("can't get psta under MP_MODE ; drop pkt\n"));
1427 #ifdef DBG_RX_DROP_FRAME
1428 DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __FUNCTION__
);
1436 else if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
1439 ret
= RTW_RX_HANDLED
;
1444 if(_rtw_memcmp(myhwaddr
, pattrib
->dst
, ETH_ALEN
)&& (!bmcast
))
1446 *psta
= rtw_get_stainfo(pstapriv
, pattrib
->bssid
); // get sta_info
1449 DBG_871X("issue_deauth to the ap=" MAC_FMT
" for the reason(7)\n", MAC_ARG(pattrib
->bssid
));
1451 issue_deauth(adapter
, pattrib
->bssid
, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1456 #ifdef DBG_RX_DROP_FRAME
1457 DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __FUNCTION__
, get_fwstate(pmlmepriv
));
1469 sint
sta2ap_data_frame(
1471 union recv_frame
*precv_frame
,
1472 struct sta_info
**psta
);
1473 sint
sta2ap_data_frame(
1475 union recv_frame
*precv_frame
,
1476 struct sta_info
**psta
)
1478 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
1479 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
1480 struct sta_priv
*pstapriv
= &adapter
->stapriv
;
1481 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1482 unsigned char *mybssid
= get_bssid(pmlmepriv
);
1487 if (check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
1489 //For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR
1490 if(!_rtw_memcmp(pattrib
->bssid
, mybssid
, ETH_ALEN
))
1496 *psta
= rtw_get_stainfo(pstapriv
, pattrib
->src
);
1499 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("can't get psta under AP_MODE; drop pkt\n"));
1500 DBG_871X("issue_deauth to sta=" MAC_FMT
" for the reason(7)\n", MAC_ARG(pattrib
->src
));
1502 issue_deauth(adapter
, pattrib
->src
, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1504 ret
= RTW_RX_HANDLED
;
1508 process_pwrbit_data(adapter
, precv_frame
);
1510 if ((GetFrameSubType(ptr
) & WIFI_QOS_DATA_TYPE
) == WIFI_QOS_DATA_TYPE
) {
1511 process_wmmps_data(adapter
, precv_frame
);
1514 if (GetFrameSubType(ptr
) & BIT(6)) {
1515 /* No data, will not indicate to upper layer, temporily count it here */
1516 count_rx_stats(adapter
, precv_frame
, *psta
);
1517 ret
= RTW_RX_HANDLED
;
1522 u8
*myhwaddr
= myid(&adapter
->eeprompriv
);
1523 if (!_rtw_memcmp(pattrib
->ra
, myhwaddr
, ETH_ALEN
)) {
1524 ret
= RTW_RX_HANDLED
;
1527 DBG_871X("issue_deauth to sta=" MAC_FMT
" for the reason(7)\n", MAC_ARG(pattrib
->src
));
1528 issue_deauth(adapter
, pattrib
->src
, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA
);
1529 ret
= RTW_RX_HANDLED
;
1541 sint
validate_recv_ctrl_frame(_adapter
*padapter
, union recv_frame
*precv_frame
);
1542 sint
validate_recv_ctrl_frame(_adapter
*padapter
, union recv_frame
*precv_frame
)
1544 #ifdef CONFIG_AP_MODE
1545 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
1546 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
1547 u8
*pframe
= precv_frame
->u
.hdr
.rx_data
;
1548 //uint len = precv_frame->u.hdr.len;
1550 //DBG_871X("+validate_recv_ctrl_frame\n");
1552 if (GetFrameType(pframe
) != WIFI_CTRL_TYPE
)
1557 //receive the frames that ra(a1) is my address
1558 if (!_rtw_memcmp(GetAddr1Ptr(pframe
), myid(&padapter
->eeprompriv
), ETH_ALEN
))
1563 //only handle ps-poll
1564 if(GetFrameSubType(pframe
) == WIFI_PSPOLL
)
1568 struct sta_info
*psta
=NULL
;
1570 aid
= GetAid(pframe
);
1571 psta
= rtw_get_stainfo(pstapriv
, GetAddr2Ptr(pframe
));
1573 if((psta
==NULL
) || (psta
->aid
!=aid
))
1578 //for rx pkt statistics
1579 psta
->sta_stats
.rx_ctrl_pkts
++;
1581 switch(pattrib
->priority
)
1585 wmmps_ac
= psta
->uapsd_bk
&BIT(0);
1589 wmmps_ac
= psta
->uapsd_vi
&BIT(0);
1593 wmmps_ac
= psta
->uapsd_vo
&BIT(0);
1598 wmmps_ac
= psta
->uapsd_be
&BIT(0);
1605 if(psta
->state
& WIFI_STA_ALIVE_CHK_STATE
)
1607 DBG_871X("%s alive check-rx ps-poll\n", __func__
);
1608 psta
->expire_to
= pstapriv
->expire_to
;
1609 psta
->state
^= WIFI_STA_ALIVE_CHK_STATE
;
1612 if((psta
->state
&WIFI_SLEEP_STATE
) && (pstapriv
->sta_dz_bitmap
&BIT(psta
->aid
)))
1615 _list
*xmitframe_plist
, *xmitframe_phead
;
1616 struct xmit_frame
*pxmitframe
=NULL
;
1617 struct xmit_priv
*pxmitpriv
= &padapter
->xmitpriv
;
1619 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
1620 _enter_critical_bh(&pxmitpriv
->lock
, &irqL
);
1622 xmitframe_phead
= get_list_head(&psta
->sleep_q
);
1623 xmitframe_plist
= get_next(xmitframe_phead
);
1625 if ((rtw_end_of_queue_search(xmitframe_phead
, xmitframe_plist
)) == _FALSE
)
1627 pxmitframe
= LIST_CONTAINOR(xmitframe_plist
, struct xmit_frame
, list
);
1629 xmitframe_plist
= get_next(xmitframe_plist
);
1631 rtw_list_delete(&pxmitframe
->list
);
1635 if(psta
->sleepq_len
>0)
1636 pxmitframe
->attrib
.mdata
= 1;
1638 pxmitframe
->attrib
.mdata
= 0;
1640 pxmitframe
->attrib
.triggered
= 1;
1642 //DBG_871X("handling ps-poll, q_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap);
1645 _exit_critical_bh(&psta
->sleep_q
.lock
, &irqL
);
1646 if(rtw_hal_xmit(padapter
, pxmitframe
) == _TRUE
)
1648 rtw_os_xmit_complete(padapter
, pxmitframe
);
1650 _enter_critical_bh(&psta
->sleep_q
.lock
, &irqL
);
1652 rtw_hal_xmitframe_enqueue(padapter
, pxmitframe
);
1654 if(psta
->sleepq_len
==0)
1656 pstapriv
->tim_bitmap
&= ~BIT(psta
->aid
);
1658 //DBG_871X("after handling ps-poll, tim=%x\n", pstapriv->tim_bitmap);
1660 //upate BCN for TIM IE
1661 //update_BCNTIM(padapter);
1662 update_beacon(padapter
, _TIM_IE_
, NULL
, _FALSE
);
1665 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
1666 _exit_critical_bh(&pxmitpriv
->lock
, &irqL
);
1671 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
1672 _exit_critical_bh(&pxmitpriv
->lock
, &irqL
);
1674 //DBG_871X("no buffered packets to xmit\n");
1675 if(pstapriv
->tim_bitmap
&BIT(psta
->aid
))
1677 if(psta
->sleepq_len
==0)
1679 DBG_871X("no buffered packets to xmit\n");
1681 //issue nulldata with More data bit = 0 to indicate we have no buffered packets
1682 issue_nulldata(padapter
, psta
->hwaddr
, 0, 0, 0);
1686 DBG_871X("error!psta->sleepq_len=%d\n", psta
->sleepq_len
);
1690 pstapriv
->tim_bitmap
&= ~BIT(psta
->aid
);
1692 //upate BCN for TIM IE
1693 //update_BCNTIM(padapter);
1694 update_beacon(padapter
, _TIM_IE_
, NULL
, _FALSE
);
1709 union recv_frame
* recvframe_chk_defrag(PADAPTER padapter
, union recv_frame
*precv_frame
);
1710 sint
validate_recv_mgnt_frame(PADAPTER padapter
, union recv_frame
*precv_frame
);
1711 sint
validate_recv_mgnt_frame(PADAPTER padapter
, union recv_frame
*precv_frame
)
1713 //struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1715 RT_TRACE(_module_rtl871x_recv_c_
, _drv_info_
, ("+validate_recv_mgnt_frame\n"));
1718 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
1720 #ifdef CONFIG_NATIVEAP_MLME
1721 mgt_dispatcher(padapter
, precv_frame
);
1723 rtw_hostapd_mlme_rx(padapter
, precv_frame
);
1728 mgt_dispatcher(padapter
, precv_frame
);
1732 precv_frame
= recvframe_chk_defrag(padapter
, precv_frame
);
1733 if (precv_frame
== NULL
) {
1734 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
,("%s: fragment packet\n",__FUNCTION__
));
1739 //for rx pkt statistics
1740 struct sta_info
*psta
= rtw_get_stainfo(&padapter
->stapriv
, GetAddr2Ptr(precv_frame
->u
.hdr
.rx_data
));
1742 psta
->sta_stats
.rx_mgnt_pkts
++;
1743 if (GetFrameSubType(precv_frame
->u
.hdr
.rx_data
) == WIFI_BEACON
)
1744 psta
->sta_stats
.rx_beacon_pkts
++;
1745 else if (GetFrameSubType(precv_frame
->u
.hdr
.rx_data
) == WIFI_PROBEREQ
)
1746 psta
->sta_stats
.rx_probereq_pkts
++;
1747 else if (GetFrameSubType(precv_frame
->u
.hdr
.rx_data
) == WIFI_PROBERSP
) {
1748 if (_rtw_memcmp(padapter
->eeprompriv
.mac_addr
, GetAddr1Ptr(precv_frame
->u
.hdr
.rx_data
), ETH_ALEN
) == _TRUE
)
1749 psta
->sta_stats
.rx_probersp_pkts
++;
1750 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame
->u
.hdr
.rx_data
))
1751 || is_multicast_mac_addr(GetAddr1Ptr(precv_frame
->u
.hdr
.rx_data
)))
1752 psta
->sta_stats
.rx_probersp_bm_pkts
++;
1754 psta
->sta_stats
.rx_probersp_uo_pkts
++;
1759 #ifdef CONFIG_INTEL_PROXIM
1760 if(padapter
->proximity
.proxim_on
==_TRUE
)
1762 struct rx_pkt_attrib
* pattrib
=&precv_frame
->u
.hdr
.attrib
;
1763 struct recv_stat
* prxstat
=( struct recv_stat
* ) precv_frame
->u
.hdr
.rx_head
;
1764 u8
* pda
,*psa
,*pbssid
,*ptr
;
1765 ptr
=precv_frame
->u
.hdr
.rx_data
;
1768 pbssid
= get_hdr_bssid(ptr
);
1771 _rtw_memcpy(pattrib
->dst
, pda
, ETH_ALEN
);
1772 _rtw_memcpy(pattrib
->src
, psa
, ETH_ALEN
);
1774 _rtw_memcpy(pattrib
->bssid
, pbssid
, ETH_ALEN
);
1776 switch(pattrib
->to_fr_ds
)
1779 _rtw_memcpy(pattrib
->ra
, pda
, ETH_ALEN
);
1780 _rtw_memcpy(pattrib
->ta
, psa
, ETH_ALEN
);
1784 _rtw_memcpy(pattrib
->ra
, pda
, ETH_ALEN
);
1785 _rtw_memcpy(pattrib
->ta
, pbssid
, ETH_ALEN
);
1789 _rtw_memcpy(pattrib
->ra
, pbssid
, ETH_ALEN
);
1790 _rtw_memcpy(pattrib
->ta
, psa
, ETH_ALEN
);
1794 _rtw_memcpy(pattrib
->ra
, GetAddr1Ptr(ptr
), ETH_ALEN
);
1795 _rtw_memcpy(pattrib
->ta
, GetAddr2Ptr(ptr
), ETH_ALEN
);
1796 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,(" case 3\n"));
1803 pattrib
->priority
=0;
1804 pattrib
->hdrlen
= pattrib
->to_fr_ds
==3 ? 30 : 24;
1806 padapter
->proximity
.proxim_rx(padapter
,precv_frame
);
1809 mgt_dispatcher(padapter
, precv_frame
);
1815 sint
validate_recv_data_frame(_adapter
*adapter
, union recv_frame
*precv_frame
);
1816 sint
validate_recv_data_frame(_adapter
*adapter
, union recv_frame
*precv_frame
)
1819 u8
*psa
, *pda
, *pbssid
;
1820 struct sta_info
*psta
= NULL
;
1821 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
1822 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
1823 struct security_priv
*psecuritypriv
= &adapter
->securitypriv
;
1824 sint ret
= _SUCCESS
;
1826 struct tdls_info
*ptdlsinfo
= &adapter
->tdlsinfo
;
1827 #endif //CONFIG_TDLS
1831 bretry
= GetRetry(ptr
);
1834 pbssid
= get_hdr_bssid(ptr
);
1841 _rtw_memcpy(pattrib
->dst
, pda
, ETH_ALEN
);
1842 _rtw_memcpy(pattrib
->src
, psa
, ETH_ALEN
);
1844 _rtw_memcpy(pattrib
->bssid
, pbssid
, ETH_ALEN
);
1846 switch(pattrib
->to_fr_ds
)
1849 _rtw_memcpy(pattrib
->ra
, pda
, ETH_ALEN
);
1850 _rtw_memcpy(pattrib
->ta
, psa
, ETH_ALEN
);
1851 ret
= sta2sta_data_frame(adapter
, precv_frame
, &psta
);
1855 _rtw_memcpy(pattrib
->ra
, pda
, ETH_ALEN
);
1856 _rtw_memcpy(pattrib
->ta
, pbssid
, ETH_ALEN
);
1857 ret
= ap2sta_data_frame(adapter
, precv_frame
, &psta
);
1861 _rtw_memcpy(pattrib
->ra
, pbssid
, ETH_ALEN
);
1862 _rtw_memcpy(pattrib
->ta
, psa
, ETH_ALEN
);
1863 ret
= sta2ap_data_frame(adapter
, precv_frame
, &psta
);
1867 _rtw_memcpy(pattrib
->ra
, GetAddr1Ptr(ptr
), ETH_ALEN
);
1868 _rtw_memcpy(pattrib
->ta
, GetAddr2Ptr(ptr
), ETH_ALEN
);
1870 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,(" case 3\n"));
1880 #ifdef DBG_RX_DROP_FRAME
1881 DBG_871X("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __FUNCTION__
, pattrib
->to_fr_ds
, ret
);
1884 } else if (ret
== RTW_RX_HANDLED
) {
1890 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,(" after to_fr_ds_chk; psta==NULL \n"));
1895 //psta->rssi = prxcmd->rssi;
1896 //psta->signal_quality= prxcmd->sq;
1897 precv_frame
->u
.hdr
.psta
= psta
;
1901 pattrib
->ack_policy
= 0;
1903 if(pattrib
->qos
== 1)
1905 pattrib
->priority
= GetPriority((ptr
+ 24));
1906 pattrib
->ack_policy
= GetAckpolicy((ptr
+ 24));
1907 pattrib
->amsdu
= GetAMsdu((ptr
+ 24));
1908 pattrib
->hdrlen
= pattrib
->to_fr_ds
==3 ? 32 : 26;
1910 if(pattrib
->priority
!=0 && pattrib
->priority
!=3)
1912 adapter
->recvpriv
.bIsAnyNonBEPkts
= _TRUE
;
1917 pattrib
->priority
=0;
1918 pattrib
->hdrlen
= pattrib
->to_fr_ds
==3 ? 30 : 24;
1922 if(pattrib
->order
)//HT-CTRL 11n
1924 pattrib
->hdrlen
+= 4;
1927 precv_frame
->u
.hdr
.preorder_ctrl
= &psta
->recvreorder_ctrl
[pattrib
->priority
];
1929 // decache, drop duplicate recv packets
1930 if(recv_decache(precv_frame
, bretry
, &psta
->sta_recvpriv
.rxcache
) == _FAIL
)
1932 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("decache : drop pkt\n"));
1938 if(psta
->tdls_sta_state
& TDLS_LINKED_STATE
)
1940 if(psta
->dot118021XPrivacy
==_AES_
)
1941 pattrib
->encrypt
=psta
->dot118021XPrivacy
;
1943 #endif //CONFIG_TDLS
1945 if(pattrib
->privacy
){
1947 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("validate_recv_data_frame:pattrib->privacy=%x\n", pattrib
->privacy
));
1948 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n ^^^^^^^^^^^IS_MCAST(pattrib->ra(0x%02x))=%d^^^^^^^^^^^^^^^6\n", pattrib
->ra
[0],IS_MCAST(pattrib
->ra
)));
1951 if((psta
->tdls_sta_state
& TDLS_LINKED_STATE
) && (psta
->dot118021XPrivacy
==_AES_
))
1953 pattrib
->encrypt
=psta
->dot118021XPrivacy
;
1956 #endif //CONFIG_TDLS
1957 GET_ENCRY_ALGO(psecuritypriv
, psta
, pattrib
->encrypt
, IS_MCAST(pattrib
->ra
));
1959 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n pattrib->encrypt=%d\n",pattrib
->encrypt
));
1961 SET_ICE_IV_LEN(pattrib
->iv_len
, pattrib
->icv_len
, pattrib
->encrypt
);
1965 pattrib
->encrypt
= 0;
1966 pattrib
->iv_len
= pattrib
->icv_len
= 0;
1976 #ifdef CONFIG_IEEE80211W
1977 static sint
validate_80211w_mgmt(_adapter
*adapter
, union recv_frame
*precv_frame
)
1979 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
1980 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
1981 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
1985 type
= GetFrameType(ptr
);
1986 subtype
= GetFrameSubType(ptr
); //bit(7)~bit(2)
1988 //only support station mode
1989 if(check_fwstate(pmlmepriv
, WIFI_STATION_STATE
) && check_fwstate(pmlmepriv
, _FW_LINKED
)
1990 && adapter
->securitypriv
.binstallBIPkey
== _TRUE
)
1992 //unicast management frame decrypt
1993 if(pattrib
->privacy
&& !(IS_MCAST(GetAddr1Ptr(ptr
))) &&
1994 (subtype
== WIFI_DEAUTH
|| subtype
== WIFI_DISASSOC
|| subtype
== WIFI_ACTION
))
1996 u8
*ppp
, *mgmt_DATA
;
1998 ppp
= GetAddr2Ptr(ptr
);
2000 pattrib
->bdecrypted
= 0;
2001 pattrib
->encrypt
= _AES_
;
2002 pattrib
->hdrlen
= sizeof(struct rtw_ieee80211_hdr_3addr
);
2003 //set iv and icv length
2004 SET_ICE_IV_LEN(pattrib
->iv_len
, pattrib
->icv_len
, pattrib
->encrypt
);
2005 _rtw_memcpy(pattrib
->ra
, GetAddr1Ptr(ptr
), ETH_ALEN
);
2006 _rtw_memcpy(pattrib
->ta
, GetAddr2Ptr(ptr
), ETH_ALEN
);
2007 //actual management data frame body
2008 data_len
= pattrib
->pkt_len
- pattrib
->hdrlen
- pattrib
->iv_len
- pattrib
->icv_len
;
2009 mgmt_DATA
= rtw_zmalloc(data_len
);
2010 if(mgmt_DATA
== NULL
)
2012 DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __FUNCTION__
);
2013 goto validate_80211w_fail
;
2015 /*//dump the packet content before decrypt
2018 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
2019 for(pp=0;pp< pattrib->pkt_len; pp++)
2020 printk(" %02x ", ptr[pp]);
2024 precv_frame
= decryptor(adapter
, precv_frame
);
2025 //save actual management data frame body
2026 _rtw_memcpy(mgmt_DATA
, ptr
+pattrib
->hdrlen
+pattrib
->iv_len
, data_len
);
2027 //overwrite the iv field
2028 _rtw_memcpy(ptr
+pattrib
->hdrlen
, mgmt_DATA
, data_len
);
2029 //remove the iv and icv length
2030 pattrib
->pkt_len
= pattrib
->pkt_len
- pattrib
->iv_len
- pattrib
->icv_len
;
2031 rtw_mfree(mgmt_DATA
, data_len
);
2032 /*//print packet content after decryption
2035 printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len);
2036 for(pp=0;pp< pattrib->pkt_len; pp++)
2037 printk(" %02x ", ptr[pp]);
2042 DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __FUNCTION__
);
2043 goto validate_80211w_fail
;
2046 else if(IS_MCAST(GetAddr1Ptr(ptr
)) &&
2047 (subtype
== WIFI_DEAUTH
|| subtype
== WIFI_DISASSOC
))
2049 sint BIP_ret
= _SUCCESS
;
2050 //verify BIP MME IE of broadcast/multicast de-auth/disassoc packet
2051 BIP_ret
= rtw_BIP_verify(adapter
, (u8
* )precv_frame
);
2052 if(BIP_ret
== _FAIL
)
2054 //DBG_871X("802.11w BIP verify fail\n");
2055 goto validate_80211w_fail
;
2057 else if(BIP_ret
== RTW_RX_HANDLED
)
2059 //DBG_871X("802.11w recv none protected packet\n");
2060 //issue sa query request
2061 issue_action_SA_Query(adapter
, NULL
, 0, 0);
2062 goto validate_80211w_fail
;
2067 if(subtype
== WIFI_ACTION
)
2069 //according 802.11-2012 standard, these five types are not robust types
2070 if( ptr
[WLAN_HDR_A3_LEN
] != RTW_WLAN_CATEGORY_PUBLIC
&&
2071 ptr
[WLAN_HDR_A3_LEN
] != RTW_WLAN_CATEGORY_HT
&&
2072 ptr
[WLAN_HDR_A3_LEN
] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM
&&
2073 ptr
[WLAN_HDR_A3_LEN
] != RTW_WLAN_CATEGORY_SELF_PROTECTED
&&
2074 ptr
[WLAN_HDR_A3_LEN
] != RTW_WLAN_CATEGORY_P2P
)
2076 DBG_871X("action frame category=%d should robust\n", ptr
[WLAN_HDR_A3_LEN
]);
2077 goto validate_80211w_fail
;
2080 else if(subtype
== WIFI_DEAUTH
|| subtype
== WIFI_DISASSOC
)
2082 DBG_871X("802.11w recv none protected packet\n");
2083 //issue sa query request
2084 issue_action_SA_Query(adapter
, NULL
, 0, 0);
2085 goto validate_80211w_fail
;
2091 validate_80211w_fail
:
2095 #endif //CONFIG_IEEE80211W
2097 sint
validate_recv_frame(_adapter
*adapter
, union recv_frame
*precv_frame
);
2098 sint
validate_recv_frame(_adapter
*adapter
, union recv_frame
*precv_frame
)
2100 //shall check frame subtype, to / from ds, da, bssid
2102 //then call check if rx seq/frag. duplicated.
2106 sint retval
= _SUCCESS
;
2108 struct rx_pkt_attrib
*pattrib
= & precv_frame
->u
.hdr
.attrib
;
2110 u8
*ptr
= precv_frame
->u
.hdr
.rx_data
;
2111 u8 ver
=(unsigned char) (*ptr
)&0x3 ;
2112 #ifdef CONFIG_FIND_BEST_CHANNEL
2113 struct mlme_ext_priv
*pmlmeext
= &adapter
->mlmeextpriv
;
2117 struct tdls_info
*ptdlsinfo
= &adapter
->tdlsinfo
;
2118 #endif //CONFIG_TDLS
2123 #ifdef CONFIG_FIND_BEST_CHANNEL
2124 if (pmlmeext
->sitesurvey_res
.state
== SCAN_PROCESS
) {
2125 int ch_set_idx
= rtw_ch_set_search_ch(pmlmeext
->channel_set
, rtw_get_oper_ch(adapter
));
2126 if (ch_set_idx
>= 0)
2127 pmlmeext
->channel_set
[ch_set_idx
].rx_count
++;
2132 if(ptdlsinfo
->ch_sensing
==1 && ptdlsinfo
->cur_channel
!=0){
2133 ptdlsinfo
->collect_pkt_num
[ptdlsinfo
->cur_channel
-1]++;
2135 #endif //CONFIG_TDLS
2137 #ifdef RTK_DMP_PLATFORM
2143 for(i
=0; i
<64;i
=i
+8)
2144 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr
+i
),
2145 *(ptr
+i
+1), *(ptr
+i
+2) ,*(ptr
+i
+3) ,*(ptr
+i
+4),*(ptr
+i
+5), *(ptr
+i
+6), *(ptr
+i
+7));
2150 #endif //RTK_DMP_PLATFORM
2154 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("validate_recv_data_frame fail! (ver!=0)\n"));
2159 type
= GetFrameType(ptr
);
2160 subtype
= GetFrameSubType(ptr
); //bit(7)~bit(2)
2162 pattrib
->to_fr_ds
= get_tofr_ds(ptr
);
2164 pattrib
->frag_num
= GetFragNum(ptr
);
2165 pattrib
->seq_num
= GetSequence(ptr
);
2167 pattrib
->pw_save
= GetPwrMgt(ptr
);
2168 pattrib
->mfrag
= GetMFrag(ptr
);
2169 pattrib
->mdata
= GetMData(ptr
);
2170 pattrib
->privacy
= GetPrivacy(ptr
);
2171 pattrib
->order
= GetOrder(ptr
);
2174 if(pHalData
->bDumpRxPkt
==1){
2176 DBG_871X("############################# \n");
2178 for(i
=0; i
<64;i
=i
+8)
2179 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr
+i
),
2180 *(ptr
+i
+1), *(ptr
+i
+2) ,*(ptr
+i
+3) ,*(ptr
+i
+4),*(ptr
+i
+5), *(ptr
+i
+6), *(ptr
+i
+7));
2181 DBG_871X("############################# \n");
2183 else if(pHalData
->bDumpRxPkt
==2){
2184 if(type
== WIFI_MGT_TYPE
){
2186 DBG_871X("############################# \n");
2188 for(i
=0; i
<64;i
=i
+8)
2189 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr
+i
),
2190 *(ptr
+i
+1), *(ptr
+i
+2) ,*(ptr
+i
+3) ,*(ptr
+i
+4),*(ptr
+i
+5), *(ptr
+i
+6), *(ptr
+i
+7));
2191 DBG_871X("############################# \n");
2194 else if(pHalData
->bDumpRxPkt
==3){
2195 if(type
== WIFI_DATA_TYPE
){
2197 DBG_871X("############################# \n");
2199 for(i
=0; i
<64;i
=i
+8)
2200 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr
+i
),
2201 *(ptr
+i
+1), *(ptr
+i
+2) ,*(ptr
+i
+3) ,*(ptr
+i
+4),*(ptr
+i
+5), *(ptr
+i
+6), *(ptr
+i
+7));
2202 DBG_871X("############################# \n");
2209 case WIFI_MGT_TYPE
: //mgnt
2210 #ifdef CONFIG_IEEE80211W
2211 if(validate_80211w_mgmt(adapter
, precv_frame
) == _FAIL
)
2216 #endif //CONFIG_IEEE80211W
2218 retval
= validate_recv_mgnt_frame(adapter
, precv_frame
);
2219 if (retval
== _FAIL
)
2221 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("validate_recv_mgnt_frame fail\n"));
2223 retval
= _FAIL
; // only data frame return _SUCCESS
2225 case WIFI_CTRL_TYPE
: //ctrl
2226 retval
= validate_recv_ctrl_frame(adapter
, precv_frame
);
2227 if (retval
== _FAIL
)
2229 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("validate_recv_ctrl_frame fail\n"));
2231 retval
= _FAIL
; // only data frame return _SUCCESS
2233 case WIFI_DATA_TYPE
: //data
2234 rtw_led_control(adapter
, LED_CTL_RX
);
2235 pattrib
->qos
= (subtype
& BIT(7))? 1:0;
2236 retval
= validate_recv_data_frame(adapter
, precv_frame
);
2237 if (retval
== _FAIL
)
2239 struct recv_priv
*precvpriv
= &adapter
->recvpriv
;
2240 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("validate_recv_data_frame fail\n"));
2241 precvpriv
->rx_drop
++;
2245 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("validate_recv_data_frame fail! type=0x%x\n", type
));
2246 #ifdef DBG_RX_DROP_FRAME
2247 DBG_871X("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type=0x%x\n", type
);
2261 //remove the wlanhdr and add the eth_hdr
2264 sint
wlanhdr_to_ethhdr ( union recv_frame
*precvframe
);
2265 sint
wlanhdr_to_ethhdr ( union recv_frame
*precvframe
)
2271 struct ieee80211_snap_hdr
*psnap
;
2274 _adapter
*adapter
=precvframe
->u
.hdr
.adapter
;
2275 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
2277 u8
*ptr
= get_recvframe_data(precvframe
) ; // point to frame_ctrl field
2278 struct rx_pkt_attrib
*pattrib
= & precvframe
->u
.hdr
.attrib
;
2282 if(pattrib
->encrypt
){
2283 recvframe_pull_tail(precvframe
, pattrib
->icv_len
);
2286 psnap
=(struct ieee80211_snap_hdr
*)(ptr
+pattrib
->hdrlen
+ pattrib
->iv_len
);
2287 psnap_type
=ptr
+pattrib
->hdrlen
+ pattrib
->iv_len
+SNAP_SIZE
;
2288 /* convert hdr + possible LLC headers into Ethernet header */
2289 //eth_type = (psnap_type[0] << 8) | psnap_type[1];
2290 if((_rtw_memcmp(psnap
, rtw_rfc1042_header
, SNAP_SIZE
) &&
2291 (_rtw_memcmp(psnap_type
, SNAP_ETH_TYPE_IPX
, 2) == _FALSE
) &&
2292 (_rtw_memcmp(psnap_type
, SNAP_ETH_TYPE_APPLETALK_AARP
, 2)==_FALSE
) )||
2293 //eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
2294 _rtw_memcmp(psnap
, rtw_bridge_tunnel_header
, SNAP_SIZE
)){
2295 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2299 /* Leave Ethernet header part of hdr and full payload */
2303 rmv_len
= pattrib
->hdrlen
+ pattrib
->iv_len
+(bsnaphdr
?SNAP_SIZE
:0);
2304 len
= precvframe
->u
.hdr
.len
- rmv_len
;
2306 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("\n===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n\n", pattrib
->hdrlen
, pattrib
->iv_len
));
2308 _rtw_memcpy(ð_type
, ptr
+rmv_len
, 2);
2309 eth_type
= ntohs((unsigned short )eth_type
); //pattrib->ether_type
2310 pattrib
->eth_type
= eth_type
;
2312 if ((check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
))
2319 // append rx status for mp test packets
2320 ptr
= recvframe_pull(precvframe
, (rmv_len
-sizeof(struct ethhdr
)+2)-24);
2321 _rtw_memcpy(ptr
, get_rxmem(precvframe
), 24);
2325 ptr
= recvframe_pull(precvframe
, (rmv_len
-sizeof(struct ethhdr
)+ (bsnaphdr
?2:0)));
2328 _rtw_memcpy(ptr
, pattrib
->dst
, ETH_ALEN
);
2329 _rtw_memcpy(ptr
+ETH_ALEN
, pattrib
->src
, ETH_ALEN
);
2333 _rtw_memcpy(ptr
+12, &len
, 2);
2343 sint
wlanhdr_to_ethhdr ( union recv_frame
*precvframe
)
2349 struct ieee80211_snap_hdr
*psnap
;
2352 _adapter
*adapter
=precvframe
->u
.hdr
.adapter
;
2353 struct mlme_priv
*pmlmepriv
= &adapter
->mlmepriv
;
2355 u8
* ptr
= get_recvframe_data(precvframe
) ; // point to frame_ctrl field
2356 struct rx_pkt_attrib
*pattrib
= & precvframe
->u
.hdr
.attrib
;
2357 struct _vlan
*pvlan
= NULL
;
2361 psnap
=(struct ieee80211_snap_hdr
*)(ptr
+pattrib
->hdrlen
+ pattrib
->iv_len
);
2362 psnap_type
=ptr
+pattrib
->hdrlen
+ pattrib
->iv_len
+SNAP_SIZE
;
2363 if (psnap
->dsap
==0xaa && psnap
->ssap
==0xaa && psnap
->ctrl
==0x03)
2365 if (_rtw_memcmp(psnap
->oui
, oui_rfc1042
, WLAN_IEEE_OUI_LEN
))
2366 bsnaphdr
=_TRUE
;//wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042;
2367 else if (_rtw_memcmp(psnap
->oui
, SNAP_HDR_APPLETALK_DDP
, WLAN_IEEE_OUI_LEN
) &&
2368 _rtw_memcmp(psnap_type
, SNAP_ETH_TYPE_APPLETALK_DDP
, 2) )
2369 bsnaphdr
=_TRUE
; //wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK;
2370 else if (_rtw_memcmp( psnap
->oui
, oui_8021h
, WLAN_IEEE_OUI_LEN
))
2371 bsnaphdr
=_TRUE
; //wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL;
2373 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("drop pkt due to invalid frame format!\n"));
2379 bsnaphdr
=_FALSE
;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS;
2381 rmv_len
= pattrib
->hdrlen
+ pattrib
->iv_len
+(bsnaphdr
?SNAP_SIZE
:0);
2382 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n", pattrib
->hdrlen
, pattrib
->iv_len
));
2384 if (check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
)
2390 //back to original pointer
2396 _rtw_memcpy(ð_type
, ptr
, 2);
2397 eth_type
= ntohs((unsigned short )eth_type
); //pattrib->ether_type
2400 if(pattrib
->encrypt
){
2401 recvframe_pull_tail(precvframe
, pattrib
->icv_len
);
2404 if(eth_type
== 0x8100) //vlan
2406 pvlan
= (struct _vlan
*) ptr
;
2408 //eth_type = get_vlan_encap_proto(pvlan);
2409 //eth_type = pvlan->h_vlan_encapsulated_proto;//?
2414 if(eth_type
==0x0800)//ip
2416 //struct iphdr* piphdr = (struct iphdr*) ptr;
2417 //__u8 tos = (unsigned char)(pattrib->priority & 0xff);
2419 //piphdr->tos = tos;
2421 //if (piphdr->protocol == 0x06)
2423 // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", precvframe->u.hdr.len));
2426 else if(eth_type
==0x8712)// append rx status for mp test packets
2429 //_rtw_memcpy(ptr, get_rxmem(precvframe), 16);
2433 #ifdef PLATFORM_OS_XP
2434 NDIS_PACKET_8021Q_INFO VlanPriInfo
;
2435 UINT32 UserPriority
= precvframe
->u
.hdr
.attrib
.priority
;
2436 UINT32 VlanID
= (pvlan
!=NULL
? get_vlan_id(pvlan
) : 0 );
2438 VlanPriInfo
.Value
= // Get current value.
2439 NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe
->u
.hdr
.pkt
, Ieee8021QInfo
);
2441 VlanPriInfo
.TagHeader
.UserPriority
= UserPriority
;
2442 VlanPriInfo
.TagHeader
.VlanId
= VlanID
;
2444 VlanPriInfo
.TagHeader
.CanonicalFormatId
= 0; // Should be zero.
2445 VlanPriInfo
.TagHeader
.Reserved
= 0; // Should be zero.
2446 NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe
->u
.hdr
.pkt
, Ieee8021QInfo
) = VlanPriInfo
.Value
;
2450 if(eth_type
==0x8712)// append rx status for mp test packets
2452 ptr
= recvframe_pull(precvframe
, (rmv_len
-sizeof(struct ethhdr
)+2)-24);
2453 _rtw_memcpy(ptr
, get_rxmem(precvframe
), 24);
2457 ptr
= recvframe_pull(precvframe
, (rmv_len
-sizeof(struct ethhdr
)+2));
2459 _rtw_memcpy(ptr
, pattrib
->dst
, ETH_ALEN
);
2460 _rtw_memcpy(ptr
+ETH_ALEN
, pattrib
->src
, ETH_ALEN
);
2462 eth_type
= htons((unsigned short)eth_type
) ;
2463 _rtw_memcpy(ptr
+12, ð_type
, 2);
2474 #ifdef CONFIG_SDIO_HCI
2475 #ifdef PLATFORM_LINUX
2476 static void recvframe_expand_pkt(
2478 union recv_frame
*prframe
)
2480 struct recv_frame_hdr
*pfhdr
;
2486 pfhdr
= &prframe
->u
.hdr
;
2488 // 6 is for IP header 8 bytes alignment in QoS packet case.
2489 if (pfhdr
->attrib
.qos
)
2494 // for first fragment packet, need to allocate
2495 // (1536 + RXDESC_SIZE + drvinfo_sz) to reassemble packet
2496 // 8 is for skb->data 8 bytes alignment.
2497 // alloc_sz = _RND(1536 + RXDESC_SIZE + pfhdr->attrib.drvinfosize + shift_sz + 8, 128);
2498 alloc_sz
= 1664; // round (1536 + 24 + 32 + shift_sz + 8) to 128 bytes alignment
2500 //3 1. alloc new skb
2501 // prepare extra space for 4 bytes alignment
2502 ppkt
= rtw_skb_alloc(alloc_sz
);
2504 if (!ppkt
) return; // no way to expand
2506 //3 2. Prepare new skb to replace & release old skb
2507 // force ppkt->data at 8-byte alignment address
2508 skb_reserve(ppkt
, 8 - ((SIZE_PTR
)ppkt
->data
& 7));
2509 // force ip_hdr at 8-byte alignment address according to shift_sz
2510 skb_reserve(ppkt
, shift_sz
);
2512 // copy data to new pkt
2513 _rtw_memcpy(skb_put(ppkt
, pfhdr
->len
), pfhdr
->rx_data
, pfhdr
->len
);
2515 rtw_skb_free(pfhdr
->pkt
);
2517 // attach new pkt to recvframe
2519 pfhdr
->rx_head
= ppkt
->head
;
2520 pfhdr
->rx_data
= ppkt
->data
;
2521 pfhdr
->rx_tail
= skb_tail_pointer(ppkt
);
2522 pfhdr
->rx_end
= skb_end_pointer(ppkt
);
2525 #warning "recvframe_expand_pkt not implement, defrag may crash system"
2530 union recv_frame
* recvframe_defrag(_adapter
*adapter
,_queue
*defrag_q
);
2531 union recv_frame
* recvframe_defrag(_adapter
*adapter
,_queue
*defrag_q
)
2533 _list
*plist
, *phead
;
2534 u8
*data
,wlanhdr_offset
;
2536 struct recv_frame_hdr
*pfhdr
,*pnfhdr
;
2537 union recv_frame
* prframe
, *pnextrframe
;
2538 _queue
*pfree_recv_queue
;
2543 pfree_recv_queue
=&adapter
->recvpriv
.free_recv_queue
;
2545 phead
= get_list_head(defrag_q
);
2546 plist
= get_next(phead
);
2547 prframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
2548 pfhdr
=&prframe
->u
.hdr
;
2549 rtw_list_delete(&(prframe
->u
.list
));
2551 if(curfragnum
!=pfhdr
->attrib
.frag_num
)
2553 //the first fragment number must be 0
2554 //free the whole queue
2555 rtw_free_recvframe(prframe
, pfree_recv_queue
);
2556 rtw_free_recvframe_queue(defrag_q
, pfree_recv_queue
);
2561 #ifdef CONFIG_SDIO_HCI
2562 recvframe_expand_pkt(adapter
, prframe
);
2567 plist
= get_list_head(defrag_q
);
2569 plist
= get_next(plist
);
2571 data
=get_recvframe_data(prframe
);
2573 while(rtw_end_of_queue_search(phead
, plist
) == _FALSE
)
2575 pnextrframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
2576 pnfhdr
=&pnextrframe
->u
.hdr
;
2579 //check the fragment sequence (2nd ~n fragment frame)
2581 if(curfragnum
!=pnfhdr
->attrib
.frag_num
)
2583 //the fragment number must be increasing (after decache)
2584 //release the defrag_q & prframe
2585 rtw_free_recvframe(prframe
, pfree_recv_queue
);
2586 rtw_free_recvframe_queue(defrag_q
, pfree_recv_queue
);
2592 //copy the 2nd~n fragment frame's payload to the first fragment
2593 //get the 2nd~last fragment frame's payload
2595 wlanhdr_offset
= pnfhdr
->attrib
.hdrlen
+ pnfhdr
->attrib
.iv_len
;
2597 recvframe_pull(pnextrframe
, wlanhdr_offset
);
2599 //append to first fragment frame's tail (if privacy frame, pull the ICV)
2600 recvframe_pull_tail(prframe
, pfhdr
->attrib
.icv_len
);
2603 _rtw_memcpy(pfhdr
->rx_tail
, pnfhdr
->rx_data
, pnfhdr
->len
);
2605 recvframe_put(prframe
, pnfhdr
->len
);
2607 pfhdr
->attrib
.icv_len
=pnfhdr
->attrib
.icv_len
;
2608 plist
= get_next(plist
);
2612 //free the defrag_q queue and return the prframe
2613 rtw_free_recvframe_queue(defrag_q
, pfree_recv_queue
);
2615 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("Performance defrag!!!!!\n"));
2622 //check if need to defrag, if needed queue the frame to defrag_q
2623 union recv_frame
* recvframe_chk_defrag(PADAPTER padapter
, union recv_frame
*precv_frame
)
2628 struct recv_frame_hdr
*pfhdr
;
2629 struct sta_info
*psta
;
2630 struct sta_priv
*pstapriv
;
2632 union recv_frame
*prtnframe
= NULL
;
2633 _queue
*pfree_recv_queue
, *pdefrag_q
;
2637 pstapriv
= &padapter
->stapriv
;
2639 pfhdr
= &precv_frame
->u
.hdr
;
2641 pfree_recv_queue
= &padapter
->recvpriv
.free_recv_queue
;
2643 //need to define struct of wlan header frame ctrl
2644 ismfrag
= pfhdr
->attrib
.mfrag
;
2645 fragnum
= pfhdr
->attrib
.frag_num
;
2647 psta_addr
= pfhdr
->attrib
.ta
;
2648 psta
= rtw_get_stainfo(pstapriv
, psta_addr
);
2651 u8 type
= GetFrameType(pfhdr
->rx_data
);
2652 if (type
!= WIFI_DATA_TYPE
) {
2653 psta
= rtw_get_bcmc_stainfo(padapter
);
2654 pdefrag_q
= &psta
->sta_recvpriv
.defrag_q
;
2659 pdefrag_q
= &psta
->sta_recvpriv
.defrag_q
;
2661 if ((ismfrag
==0) && (fragnum
==0))
2663 prtnframe
= precv_frame
;//isn't a fragment frame
2668 //0~(n-1) fragment frame
2669 //enqueue to defraf_g
2670 if(pdefrag_q
!= NULL
)
2674 //the first fragment
2675 if(_rtw_queue_empty(pdefrag_q
) == _FALSE
)
2677 //free current defrag_q
2678 rtw_free_recvframe_queue(pdefrag_q
, pfree_recv_queue
);
2683 //Then enqueue the 0~(n-1) fragment into the defrag_q
2685 //_rtw_spinlock(&pdefrag_q->lock);
2686 phead
= get_list_head(pdefrag_q
);
2687 rtw_list_insert_tail(&pfhdr
->list
, phead
);
2688 //_rtw_spinunlock(&pdefrag_q->lock);
2690 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("Enqueuq: ismfrag = %d, fragnum= %d\n", ismfrag
,fragnum
));
2697 //can't find this ta's defrag_queue, so free this recv_frame
2698 rtw_free_recvframe(precv_frame
, pfree_recv_queue
);
2700 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag
, fragnum
));
2705 if((ismfrag
==0)&&(fragnum
!=0))
2707 //the last fragment frame
2708 //enqueue the last fragment
2709 if(pdefrag_q
!= NULL
)
2711 //_rtw_spinlock(&pdefrag_q->lock);
2712 phead
= get_list_head(pdefrag_q
);
2713 rtw_list_insert_tail(&pfhdr
->list
,phead
);
2714 //_rtw_spinunlock(&pdefrag_q->lock);
2716 //call recvframe_defrag to defrag
2717 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("defrag: ismfrag = %d, fragnum= %d\n", ismfrag
, fragnum
));
2718 precv_frame
= recvframe_defrag(padapter
, pdefrag_q
);
2719 prtnframe
=precv_frame
;
2724 //can't find this ta's defrag_queue, so free this recv_frame
2725 rtw_free_recvframe(precv_frame
, pfree_recv_queue
);
2727 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag
,fragnum
));
2733 if((prtnframe
!=NULL
)&&(prtnframe
->u
.hdr
.attrib
.privacy
))
2735 //after defrag we must check tkip mic code
2736 if(recvframe_chkmic(padapter
, prtnframe
)==_FAIL
)
2738 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("recvframe_chkmic(padapter, prtnframe)==_FAIL\n"));
2739 rtw_free_recvframe(prtnframe
,pfree_recv_queue
);
2750 #define ENDIAN_FREE 1
2752 int amsdu_to_msdu(_adapter
*padapter
, union recv_frame
*prframe
);
2753 int amsdu_to_msdu(_adapter
*padapter
, union recv_frame
*prframe
)
2755 #if defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD) //for amsdu TP improvement,Creator: Thomas
2756 int a_len
, padding_len
;
2757 u16 eth_type
, nSubframe_Length
;
2759 unsigned char *pdata
;
2760 struct rx_pkt_attrib
*pattrib
;
2761 #ifndef PLATFORM_FREEBSD
2762 unsigned char *data_ptr
;
2763 _pkt
*sub_skb
,*subframes
[MAX_SUBFRAME_COUNT
];
2764 #endif //PLATFORM_FREEBSD
2765 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
2766 _queue
*pfree_recv_queue
= &(precvpriv
->free_recv_queue
);
2768 #ifdef PLATFORM_FREEBSD
2769 struct mbuf
*sub_m
=NULL
, *subframes
[MAX_SUBFRAME_COUNT
];
2771 #endif //PLATFORM_FREEBSD
2774 pattrib
= &prframe
->u
.hdr
.attrib
;
2776 recvframe_pull(prframe
, prframe
->u
.hdr
.attrib
.hdrlen
);
2778 if(prframe
->u
.hdr
.attrib
.iv_len
>0)
2780 recvframe_pull(prframe
, prframe
->u
.hdr
.attrib
.iv_len
);
2783 a_len
= prframe
->u
.hdr
.len
;
2785 pdata
= prframe
->u
.hdr
.rx_data
;
2787 while(a_len
> ETH_HLEN
) {
2789 /* Offset 12 denote 2 mac address */
2791 //nSubframe_Length = ntohs(*((u16*)(pdata + 12)));
2792 nSubframe_Length
= RTW_GET_BE16(pdata
+ 12);
2793 #else // ENDIAN_FREE
2794 nSubframe_Length
= *((u16
*)(pdata
+ 12));
2795 //==m==>change the length order
2796 nSubframe_Length
= (nSubframe_Length
>>8) + (nSubframe_Length
<<8);
2797 //ntohs(nSubframe_Length);
2798 #endif // ENDIAN_FREE
2800 if( a_len
< (ETHERNET_HEADER_SIZE
+ nSubframe_Length
) ) {
2801 DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n",a_len
,nSubframe_Length
);
2805 #ifndef PLATFORM_FREEBSD
2806 /* move the data point to data content */
2810 /* Allocate new skb for releasing to upper layer */
2811 #ifdef CONFIG_SKB_COPY
2812 sub_skb
= rtw_skb_alloc(nSubframe_Length
+ 12);
2815 skb_reserve(sub_skb
, 12);
2816 data_ptr
= (u8
*)skb_put(sub_skb
, nSubframe_Length
);
2817 _rtw_memcpy(data_ptr
, pdata
, nSubframe_Length
);
2820 #endif // CONFIG_SKB_COPY
2822 sub_skb
= rtw_skb_clone(prframe
->u
.hdr
.pkt
);
2825 sub_skb
->data
= pdata
;
2826 sub_skb
->len
= nSubframe_Length
;
2827 skb_set_tail_pointer(sub_skb
, nSubframe_Length
);
2831 DBG_871X("rtw_skb_clone() Fail!!! , nr_subframes = %d\n",nr_subframes
);
2836 #else // PLATFORM_FREEBSD
2840 //sub_m =m_devget(pdata, nSubframe_Length+12, 12, padapter->pifp,NULL);
2841 sub_m
=m_devget(pdata
, nSubframe_Length
+ETH_HLEN
, ETHER_ALIGN
, padapter
->pifp
,NULL
);
2845 #endif // PLATFORM_FREEBSD
2847 #ifndef PLATFORM_FREEBSD
2848 //sub_skb->dev = padapter->pnetdev;
2849 subframes
[nr_subframes
++] = sub_skb
;
2850 #else //PLATFORM_FREEBSD
2852 subframes
[nr_subframes
++] = sub_m
;
2853 #endif //PLATFORM_FREEBSD
2855 if(nr_subframes
>= MAX_SUBFRAME_COUNT
) {
2856 DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n");
2860 pdata
+= nSubframe_Length
;
2861 a_len
-= nSubframe_Length
;
2863 padding_len
= 4 - ((nSubframe_Length
+ ETH_HLEN
) & (4-1));
2864 if(padding_len
== 4) {
2868 if(a_len
< padding_len
) {
2871 pdata
+= padding_len
;
2872 a_len
-= padding_len
;
2876 for(i
=0; i
<nr_subframes
; i
++){
2877 #ifndef PLATFORM_FREEBSD
2878 sub_skb
= subframes
[i
];
2879 /* convert hdr + possible LLC headers into Ethernet header */
2881 //eth_type = ntohs(*(u16*)&sub_skb->data[6]);
2882 eth_type
= RTW_GET_BE16(&sub_skb
->data
[6]);
2883 #else // ENDIAN_FREE
2884 eth_type
= (sub_skb
->data
[6] << 8) | sub_skb
->data
[7];
2885 #endif // ENDIAN_FREE
2886 if (sub_skb
->len
>= 8 &&
2887 ((_rtw_memcmp(sub_skb
->data
, rtw_rfc1042_header
, SNAP_SIZE
) &&
2888 eth_type
!= ETH_P_AARP
&& eth_type
!= ETH_P_IPX
) ||
2889 _rtw_memcmp(sub_skb
->data
, rtw_bridge_tunnel_header
, SNAP_SIZE
) )) {
2890 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2891 skb_pull(sub_skb
, SNAP_SIZE
);
2892 _rtw_memcpy(skb_push(sub_skb
, ETH_ALEN
), pattrib
->src
, ETH_ALEN
);
2893 _rtw_memcpy(skb_push(sub_skb
, ETH_ALEN
), pattrib
->dst
, ETH_ALEN
);
2896 /* Leave Ethernet header part of hdr and full payload */
2897 len
= htons(sub_skb
->len
);
2898 _rtw_memcpy(skb_push(sub_skb
, 2), &len
, 2);
2899 _rtw_memcpy(skb_push(sub_skb
, ETH_ALEN
), pattrib
->src
, ETH_ALEN
);
2900 _rtw_memcpy(skb_push(sub_skb
, ETH_ALEN
), pattrib
->dst
, ETH_ALEN
);
2903 /* Indicat the packets to upper layer */
2905 //memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
2907 #ifdef CONFIG_BR_EXT
2908 // Insert NAT2.5 RX here!
2909 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
2910 void *br_port
= NULL
;
2912 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2913 br_port
= padapter
->pnetdev
->br_port
;
2914 #else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2916 br_port
= rcu_dereference(padapter
->pnetdev
->rx_handler_data
);
2918 #endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2921 if( br_port
&& (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
|WIFI_ADHOC_STATE
) == _TRUE
) )
2923 int nat25_handle_frame(_adapter
*priv
, struct sk_buff
*skb
);
2924 if (nat25_handle_frame(padapter
, sub_skb
) == -1) {
2925 //priv->ext_stats.rx_data_drops++;
2926 //DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n");
2930 // bypass this frame to upper layer!!
2932 rtw_skb_free(sub_skb
);
2937 #endif // CONFIG_BR_EXT
2939 sub_skb
->protocol
= eth_type_trans(sub_skb
, padapter
->pnetdev
);
2940 sub_skb
->dev
= padapter
->pnetdev
;
2942 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
2943 if ( (pattrib
->tcpchk_valid
== 1) && (pattrib
->tcp_chkrpt
== 1) ) {
2944 sub_skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
2946 sub_skb
->ip_summed
= CHECKSUM_NONE
;
2948 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
2949 sub_skb
->ip_summed
= CHECKSUM_NONE
;
2950 #endif //CONFIG_TCP_CSUM_OFFLOAD_RX
2952 rtw_netif_rx(padapter
->pnetdev
, sub_skb
);
2954 #else //PLATFORM_FREEBSD
2957 sub_m
= subframes
[i
];
2958 ptr
=mtod(sub_m
, u8
*);
2960 /* convert hdr + possible LLC headers into Ethernet header */
2962 eth_type
= ntohs(*(u16
*)&ptr
[offset
+6]);
2963 #else // ENDIAN_FREE
2964 eth_type
= ( ptr
[offset
+6] << 8) | ptr
[offset
+7];
2965 #endif // ENDIAN_FREE
2966 if (sub_m
->m_pkthdr
.len
>= ETH_HLEN
+8 &&
2967 ((_rtw_memcmp(ptr
+ETH_HLEN
, rtw_rfc1042_header
, SNAP_SIZE
) &&
2968 eth_type
!= ETH_P_AARP
&& eth_type
!= ETH_P_IPX
) ||
2969 _rtw_memcmp(ptr
+ETH_HLEN
, rtw_bridge_tunnel_header
, SNAP_SIZE
) )) {
2970 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
2972 _rtw_memcpy(&ptr
[offset
-ETH_ALEN
], pattrib
->src
, ETH_ALEN
);
2974 _rtw_memcpy(&ptr
[offset
-ETH_ALEN
], pattrib
->dst
, ETH_ALEN
);
2978 /* Leave Ethernet header part of hdr and full payload */
2979 len
= htons(sub_m
->m_pkthdr
.len
-offset
);
2980 _rtw_memcpy(&ptr
[offset
- 2], &len
, 2);
2982 _rtw_memcpy(&ptr
[offset
-ETH_ALEN
], pattrib
->src
, ETH_ALEN
);
2984 _rtw_memcpy(&ptr
[offset
-ETH_ALEN
], pattrib
->dst
, ETH_ALEN
);
2988 m_adj(sub_m
,offset
);
2990 /* Indicat the packets to upper layer */
2994 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
2995 if ( (pattrib
->tcpchk_valid
== 1) && (pattrib
->tcp_chkrpt
== 1) ) {
2996 sub_skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
2998 sub_skb
->ip_summed
= CHECKSUM_NONE
;
3000 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
3001 sub_skb
->ip_summed
= CHECKSUM_NONE
;
3002 #endif //CONFIG_TCP_CSUM_OFFLOAD_RX
3005 if ( ((u32
)(mtod(sub_m
, caddr_t
) + 14) % 4) != 0)
3006 printf("%s()-%d: mtod(sub_m) = %p\n", __FUNCTION__
, __LINE__
, mtod(sub_m
, caddr_t
));
3007 #ifdef CONFIG_RX_INDICATE_QUEUE
3008 IF_ENQUEUE(&precvpriv
->rx_indicate_queue
, sub_m
);
3009 if (_IF_QLEN(&precvpriv
->rx_indicate_queue
) <= 1) {
3010 taskqueue_enqueue(taskqueue_thread
, &precvpriv
->rx_indicate_tasklet
);
3012 #else // CONFIG_RX_INDICATE_QUEUE
3013 (*padapter
->pifp
->if_input
)(padapter
->pifp
, sub_m
);
3014 #endif // CONFIG_RX_INDICATE_QUEUE
3017 #endif //PLATFORM_FREEBSD
3022 prframe
->u
.hdr
.len
=0;
3023 rtw_free_recvframe(prframe
, pfree_recv_queue
);//free this recv_frame
3026 #else // || defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
3027 #ifdef PLATFORM_WINDOWS
3029 #endif //PLATFORM_WINDOWS
3030 unsigned char *ptr
, *pdata
, *pbuf
, *psnap_type
;
3031 union recv_frame
*pnrframe
, *pnrframe_new
;
3032 int a_len
, mv_len
, padding_len
;
3033 u16 eth_type
, type_len
;
3035 struct ieee80211_snap_hdr
*psnap
;
3036 struct _vlan
*pvlan
;
3037 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
3038 _queue
*pfree_recv_queue
= &(precvpriv
->free_recv_queue
);
3040 #ifdef PLATFORM_WINDOWS
3041 struct recv_buf
*precvbuf
= prframe
->u
.hdr
.precvbuf
;
3042 #endif //PLATFORM_WINDOWS
3043 a_len
= prframe
->u
.hdr
.len
- prframe
->u
.hdr
.attrib
.hdrlen
;
3045 recvframe_pull(prframe
, prframe
->u
.hdr
.attrib
.hdrlen
);
3047 if(prframe
->u
.hdr
.attrib
.iv_len
>0)
3049 recvframe_pull(prframe
, prframe
->u
.hdr
.attrib
.iv_len
);
3052 pdata
= prframe
->u
.hdr
.rx_data
;
3054 prframe
->u
.hdr
.len
=0;
3062 pnrframe
->u
.hdr
.rx_data
= pnrframe
->u
.hdr
.rx_tail
= pdata
;
3066 _rtw_memcpy(pnrframe
->u
.hdr
.attrib
.dst
, ptr
, ETH_ALEN
);
3068 _rtw_memcpy(pnrframe
->u
.hdr
.attrib
.src
, ptr
, ETH_ALEN
);
3071 _rtw_memcpy(&type_len
, ptr
, 2);
3072 type_len
= ntohs((unsigned short )type_len
);
3076 recvframe_put(pnrframe
, type_len
+ETH_HLEN
);//update tail;
3078 if(pnrframe
->u
.hdr
.rx_data
>= pnrframe
->u
.hdr
.rx_tail
|| type_len
<8)
3080 //panic("pnrframe->u.hdr.rx_data >= pnrframe->u.hdr.rx_tail || type_len<8\n");
3082 rtw_free_recvframe(pnrframe
, pfree_recv_queue
);
3087 psnap
=(struct ieee80211_snap_hdr
*)(ptr
);
3088 psnap_type
=ptr
+SNAP_SIZE
;
3089 if (psnap
->dsap
==0xaa && psnap
->ssap
==0xaa && psnap
->ctrl
==0x03)
3091 if ( _rtw_memcmp(psnap
->oui
, oui_rfc1042
, WLAN_IEEE_OUI_LEN
))
3093 bsnaphdr
=_TRUE
;//wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042;
3095 else if (_rtw_memcmp(psnap
->oui
, SNAP_HDR_APPLETALK_DDP
, WLAN_IEEE_OUI_LEN
) &&
3096 _rtw_memcmp(psnap_type
, SNAP_ETH_TYPE_APPLETALK_DDP
, 2) )
3098 bsnaphdr
=_TRUE
; //wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK;
3100 else if (_rtw_memcmp( psnap
->oui
, oui_8021h
, WLAN_IEEE_OUI_LEN
))
3102 bsnaphdr
=_TRUE
; //wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL;
3106 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("drop pkt due to invalid frame format!\n"));
3108 //KeBugCheckEx(0x87123333, 0xe0, 0x4c, 0x87, 0xdd);
3110 //panic("0x87123333, 0xe0, 0x4c, 0x87, 0xdd\n");
3112 rtw_free_recvframe(pnrframe
, pfree_recv_queue
);
3120 bsnaphdr
=_FALSE
;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS;
3123 ptr
+= (bsnaphdr
?SNAP_SIZE
:0);
3124 _rtw_memcpy(ð_type
, ptr
, 2);
3125 eth_type
= ntohs((unsigned short )eth_type
); //pattrib->ether_type
3127 mv_len
+= 2+(bsnaphdr
?SNAP_SIZE
:0);
3128 ptr
+= 2;//now move to iphdr;
3131 if(eth_type
== 0x8100) //vlan
3133 pvlan
= (struct _vlan
*)ptr
;
3138 if(eth_type
==0x0800)//ip
3140 struct iphdr
* piphdr
= (struct iphdr
*)ptr
;
3143 if (piphdr
->protocol
== 0x06)
3145 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("@@@===recv tcp len:%d @@@===\n", pnrframe
->u
.hdr
.len
));
3148 #ifdef PLATFORM_OS_XP
3151 NDIS_PACKET_8021Q_INFO VlanPriInfo
;
3152 UINT32 UserPriority
= pnrframe
->u
.hdr
.attrib
.priority
;
3153 UINT32 VlanID
= (pvlan
!=NULL
? get_vlan_id(pvlan
) : 0 );
3155 VlanPriInfo
.Value
= // Get current value.
3156 NDIS_PER_PACKET_INFO_FROM_PACKET(pnrframe
->u
.hdr
.pkt
, Ieee8021QInfo
);
3158 VlanPriInfo
.TagHeader
.UserPriority
= UserPriority
;
3159 VlanPriInfo
.TagHeader
.VlanId
= VlanID
;
3161 VlanPriInfo
.TagHeader
.CanonicalFormatId
= 0; // Should be zero.
3162 VlanPriInfo
.TagHeader
.Reserved
= 0; // Should be zero.
3163 NDIS_PER_PACKET_INFO_FROM_PACKET(pnrframe
->u
.hdr
.pkt
, Ieee8021QInfo
) = VlanPriInfo
.Value
;
3166 #endif //PLATFORM_OS_XP
3168 pbuf
= recvframe_pull(pnrframe
, (mv_len
-sizeof(struct ethhdr
)));
3170 _rtw_memcpy(pbuf
, pnrframe
->u
.hdr
.attrib
.dst
, ETH_ALEN
);
3171 _rtw_memcpy(pbuf
+ETH_ALEN
, pnrframe
->u
.hdr
.attrib
.src
, ETH_ALEN
);
3173 eth_type
= htons((unsigned short)eth_type
) ;
3174 _rtw_memcpy(pbuf
+12, ð_type
, 2);
3176 padding_len
= (4) - ((type_len
+ ETH_HLEN
)&(4-1));
3178 a_len
-= (type_len
+ ETH_HLEN
+ padding_len
) ;
3183 if(a_len
> ETH_HLEN
)
3185 pnrframe_new
= rtw_alloc_recvframe(pfree_recv_queue
);
3189 unsigned int copy_len
= pnrframe
->u
.hdr
.len
;
3191 _rtw_init_listhead(&pnrframe_new
->u
.hdr
.list
);
3193 pskb_copy
= rtw_skb_alloc(copy_len
+64);
3197 DBG_871X("amsdu_to_msdu:can not all(ocate memory for skb copy\n");
3200 pnrframe_new
->u
.hdr
.pkt
= pskb_copy
;
3202 _rtw_memcpy(pskb_copy
->data
, pnrframe
->u
.hdr
.rx_data
, copy_len
);
3204 pnrframe_new
->u
.hdr
.rx_data
= pnrframe
->u
.hdr
.rx_data
;
3205 pnrframe_new
->u
.hdr
.rx_tail
= pnrframe
->u
.hdr
.rx_data
+ copy_len
;
3208 if ((padapter
->bDriverStopped
==_FALSE
)&&( padapter
->bSurpriseRemoved
==_FALSE
))
3210 rtw_recv_indicatepkt(padapter
, pnrframe_new
);//indicate this recv_frame
3214 rtw_free_recvframe(pnrframe_new
, pfree_recv_queue
);//free this recv_frame
3220 DBG_871X("amsdu_to_msdu:can not allocate memory for pnrframe_new\n");
3226 if ((padapter
->bDriverStopped
==_FALSE
)&&( padapter
->bSurpriseRemoved
==_FALSE
))
3228 rtw_recv_indicatepkt(padapter
, pnrframe
);//indicate this recv_frame
3232 rtw_free_recvframe(pnrframe
, pfree_recv_queue
);//free this recv_frame
3241 //padding_len = (4) - ((type_len + ETH_HLEN)&(4-1));
3243 //a_len -= (type_len + ETH_HLEN + padding_len) ;
3245 pnrframe_new
= NULL
;
3248 if(a_len
> ETH_HLEN
)
3250 pnrframe_new
= rtw_alloc_recvframe(pfree_recv_queue
);
3256 //pnrframe_new->u.hdr.precvbuf = precvbuf;//precvbuf is assigned before call rtw_init_recvframe()
3257 //rtw_init_recvframe(pnrframe_new, precvpriv);
3259 #ifdef PLATFORM_LINUX
3260 _pkt
*pskb
= pnrframe
->u
.hdr
.pkt
;
3261 #endif //PLATFORM_LINUX
3262 _rtw_init_listhead(&pnrframe_new
->u
.hdr
.list
);
3264 pnrframe_new
->u
.hdr
.len
=0;
3266 #ifdef PLATFORM_LINUX
3269 pnrframe_new
->u
.hdr
.pkt
= rtw_skb_clone(pskb
);
3271 #endif //PLATFORM_LINUX
3275 pdata
+= (type_len
+ ETH_HLEN
+ padding_len
);
3276 pnrframe_new
->u
.hdr
.rx_head
= pnrframe_new
->u
.hdr
.rx_data
= pnrframe_new
->u
.hdr
.rx_tail
= pdata
;
3277 pnrframe_new
->u
.hdr
.rx_end
= pdata
+ a_len
+ padding_len
;//
3279 #ifdef PLATFORM_WINDOWS
3280 pnrframe_new
->u
.hdr
.precvbuf
=precvbuf
;
3281 _enter_critical_bh(&precvbuf
->recvbuf_lock
, &irql
);
3282 precvbuf
->ref_cnt
++;
3283 _exit_critical_bh(&precvbuf
->recvbuf_lock
, &irql
);
3284 #endif //PLATFORM_WINDOWS
3289 //panic("pnrframe_new=%x\n", pnrframe_new);
3294 if ((padapter
->bDriverStopped
==_FALSE
)&&( padapter
->bSurpriseRemoved
==_FALSE
) )
3296 rtw_recv_indicatepkt(padapter
, pnrframe
);//indicate this recv_frame
3300 rtw_free_recvframe(pnrframe
, pfree_recv_queue
);//free this recv_frame
3307 pnrframe
= pnrframe_new
;
3311 #endif // end defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
3321 int check_indicate_seq(struct recv_reorder_ctrl
*preorder_ctrl
, u16 seq_num
);
3322 int check_indicate_seq(struct recv_reorder_ctrl
*preorder_ctrl
, u16 seq_num
)
3324 u8 wsize
= preorder_ctrl
->wsize_b
;
3325 u16 wend
= (preorder_ctrl
->indicate_seq
+ wsize
-1) & 0xFFF;//% 4096;
3327 // Rx Reorder initialize condition.
3328 if (preorder_ctrl
->indicate_seq
== 0xFFFF)
3330 preorder_ctrl
->indicate_seq
= seq_num
;
3332 DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3333 preorder_ctrl
->indicate_seq
, seq_num
);
3336 //DbgPrint("check_indicate_seq, 1st->indicate_seq=%d\n", precvpriv->indicate_seq);
3339 //DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num);
3341 // Drop out the packet which SeqNum is smaller than WinStart
3342 if( SN_LESS(seq_num
, preorder_ctrl
->indicate_seq
) )
3344 //RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum));
3345 //DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num);
3347 #ifdef DBG_RX_DROP_FRAME
3348 DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __FUNCTION__
,
3349 preorder_ctrl
->indicate_seq
, seq_num
);
3357 // Sliding window manipulation. Conditions includes:
3358 // 1. Incoming SeqNum is equal to WinStart =>Window shift 1
3359 // 2. Incoming SeqNum is larger than the WinEnd => Window shift N
3361 if( SN_EQUAL(seq_num
, preorder_ctrl
->indicate_seq
) )
3363 preorder_ctrl
->indicate_seq
= (preorder_ctrl
->indicate_seq
+ 1) & 0xFFF;
3365 DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3366 preorder_ctrl
->indicate_seq
, seq_num
);
3369 else if(SN_LESS(wend
, seq_num
))
3371 //RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum));
3372 //DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num);
3374 // boundary situation, when seq_num cross 0xFFF
3375 if(seq_num
>= (wsize
- 1))
3376 preorder_ctrl
->indicate_seq
= seq_num
+ 1 -wsize
;
3378 preorder_ctrl
->indicate_seq
= 0xFFF - (wsize
- (seq_num
+ 1)) + 1;
3381 DBG_871X("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3382 preorder_ctrl
->indicate_seq
, seq_num
);
3386 //DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num);
3391 int enqueue_reorder_recvframe(struct recv_reorder_ctrl
*preorder_ctrl
, union recv_frame
*prframe
);
3392 int enqueue_reorder_recvframe(struct recv_reorder_ctrl
*preorder_ctrl
, union recv_frame
*prframe
)
3394 struct rx_pkt_attrib
*pattrib
= &prframe
->u
.hdr
.attrib
;
3395 _queue
*ppending_recvframe_queue
= &preorder_ctrl
->pending_recvframe_queue
;
3396 _list
*phead
, *plist
;
3397 union recv_frame
*pnextrframe
;
3398 struct rx_pkt_attrib
*pnextattrib
;
3400 //DbgPrint("+enqueue_reorder_recvframe()\n");
3402 //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql);
3403 //_rtw_spinlock_ex(&ppending_recvframe_queue->lock);
3406 phead
= get_list_head(ppending_recvframe_queue
);
3407 plist
= get_next(phead
);
3409 while(rtw_end_of_queue_search(phead
, plist
) == _FALSE
)
3411 pnextrframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
3412 pnextattrib
= &pnextrframe
->u
.hdr
.attrib
;
3414 if(SN_LESS(pnextattrib
->seq_num
, pattrib
->seq_num
))
3416 plist
= get_next(plist
);
3418 else if( SN_EQUAL(pnextattrib
->seq_num
, pattrib
->seq_num
))
3420 //Duplicate entry is found!! Do not insert current entry.
3421 //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum));
3423 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3432 //DbgPrint("enqueue_reorder_recvframe():while\n");
3437 //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql);
3438 //_rtw_spinlock_ex(&ppending_recvframe_queue->lock);
3440 rtw_list_delete(&(prframe
->u
.hdr
.list
));
3442 rtw_list_insert_tail(&(prframe
->u
.hdr
.list
), plist
);
3444 //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock);
3445 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3448 //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum));
3453 int recv_indicatepkts_in_order(_adapter
*padapter
, struct recv_reorder_ctrl
*preorder_ctrl
, int bforced
);
3454 int recv_indicatepkts_in_order(_adapter
*padapter
, struct recv_reorder_ctrl
*preorder_ctrl
, int bforced
)
3458 _list
*phead
, *plist
;
3459 union recv_frame
*prframe
;
3460 struct rx_pkt_attrib
*pattrib
;
3462 int bPktInBuf
= _FALSE
;
3463 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
3464 _queue
*ppending_recvframe_queue
= &preorder_ctrl
->pending_recvframe_queue
;
3466 //DbgPrint("+recv_indicatepkts_in_order\n");
3468 //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql);
3469 //_rtw_spinlock_ex(&ppending_recvframe_queue->lock);
3471 phead
= get_list_head(ppending_recvframe_queue
);
3472 plist
= get_next(phead
);
3475 // Check if there is any other indication thread running.
3476 if(pTS
->RxIndicateState
== RXTS_INDICATE_PROCESSING
)
3480 // Handling some condition for forced indicate case.
3483 if(rtw_is_list_empty(phead
))
3485 // _exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3486 //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock);
3490 prframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
3491 pattrib
= &prframe
->u
.hdr
.attrib
;
3492 preorder_ctrl
->indicate_seq
= pattrib
->seq_num
;
3494 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3495 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
);
3499 // Prepare indication list and indication.
3500 // Check if there is any packet need indicate.
3501 while(!rtw_is_list_empty(phead
))
3504 prframe
= LIST_CONTAINOR(plist
, union recv_frame
, u
);
3505 pattrib
= &prframe
->u
.hdr
.attrib
;
3507 if(!SN_LESS(preorder_ctrl
->indicate_seq
, pattrib
->seq_num
))
3509 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
,
3510 ("recv_indicatepkts_in_order: indicate=%d seq=%d amsdu=%d\n",
3511 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
, pattrib
->amsdu
));
3514 // This protect buffer from overflow.
3515 if(index
>= REORDER_WIN_SIZE
)
3517 RT_ASSERT(FALSE
, ("IndicateRxReorderList(): Buffer overflow!! \n"));
3523 plist
= get_next(plist
);
3524 rtw_list_delete(&(prframe
->u
.hdr
.list
));
3526 if(SN_EQUAL(preorder_ctrl
->indicate_seq
, pattrib
->seq_num
))
3528 preorder_ctrl
->indicate_seq
= (preorder_ctrl
->indicate_seq
+ 1) & 0xFFF;
3530 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3531 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
);
3539 //Cancel previous pending timer.
3540 //PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer);
3543 //DBG_871X("_cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);\n");
3544 _cancel_timer(&preorder_ctrl
->reordering_ctrl_timer
, &bcancelled
);
3549 //Set this as a lock to make sure that only one thread is indicating packet.
3550 //pTS->RxIndicateState = RXTS_INDICATE_PROCESSING;
3553 //RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"));
3556 //indicate this recv_frame
3557 //DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num);
3560 //DBG_871X("recv_indicatepkts_in_order, amsdu!=1, indicate_seq=%d, seq_num=%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num);
3562 if ((padapter
->bDriverStopped
== _FALSE
) &&
3563 (padapter
->bSurpriseRemoved
== _FALSE
))
3566 rtw_recv_indicatepkt(padapter
, prframe
);//indicate this recv_frame
3570 else if(pattrib
->amsdu
==1)
3572 if(amsdu_to_msdu(padapter
, prframe
)!=_SUCCESS
)
3574 rtw_free_recvframe(prframe
, &precvpriv
->free_recv_queue
);
3583 //Update local variables.
3593 //DbgPrint("recv_indicatepkts_in_order():while\n");
3597 //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock);
3598 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3601 //Release the indication lock and set to new indication step.
3604 // Set new pending timer.
3605 //pTS->RxIndicateState = RXTS_INDICATE_REORDER;
3606 //PlatformSetTimer(Adapter, &pTS->RxPktPendingTimer, pHTInfo->RxReorderPendingTime);
3607 //DBG_871X("_set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME)\n");
3608 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3612 //pTS->RxIndicateState = RXTS_INDICATE_IDLE;
3615 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3622 int recv_indicatepkt_reorder(_adapter
*padapter
, union recv_frame
*prframe
);
3623 int recv_indicatepkt_reorder(_adapter
*padapter
, union recv_frame
*prframe
)
3626 int retval
= _SUCCESS
;
3627 struct rx_pkt_attrib
*pattrib
= &prframe
->u
.hdr
.attrib
;
3628 struct recv_reorder_ctrl
*preorder_ctrl
= prframe
->u
.hdr
.preorder_ctrl
;
3629 _queue
*ppending_recvframe_queue
= &preorder_ctrl
->pending_recvframe_queue
;
3634 wlanhdr_to_ethhdr(prframe
);
3636 //if ((pattrib->qos!=1) /*|| pattrib->priority!=0 || IS_MCAST(pattrib->ra)*/
3637 // || (pattrib->eth_type==0x0806) || (pattrib->ack_policy!=0))
3638 if (pattrib
->qos
!=1)
3640 if ((padapter
->bDriverStopped
== _FALSE
) &&
3641 (padapter
->bSurpriseRemoved
== _FALSE
))
3643 RT_TRACE(_module_rtl871x_recv_c_
, _drv_alert_
, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n" ));
3645 rtw_recv_indicatepkt(padapter
, prframe
);
3650 #ifdef DBG_RX_DROP_FRAME
3651 DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos !=1\n", __FUNCTION__
);
3658 if (preorder_ctrl
->enable
== _FALSE
)
3660 //indicate this recv_frame
3661 preorder_ctrl
->indicate_seq
= pattrib
->seq_num
;
3663 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3664 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
);
3667 rtw_recv_indicatepkt(padapter
, prframe
);
3669 preorder_ctrl
->indicate_seq
= (preorder_ctrl
->indicate_seq
+ 1)%4096;
3671 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3672 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
);
3678 #ifndef CONFIG_RECV_REORDERING_CTRL
3679 //indicate this recv_frame
3680 rtw_recv_indicatepkt(padapter
, prframe
);
3685 else if(pattrib
->amsdu
==1) //temp filter -> means didn't support A-MSDUs in a A-MPDU
3687 if (preorder_ctrl
->enable
== _FALSE
)
3689 preorder_ctrl
->indicate_seq
= pattrib
->seq_num
;
3691 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3692 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
);
3695 retval
= amsdu_to_msdu(padapter
, prframe
);
3697 preorder_ctrl
->indicate_seq
= (preorder_ctrl
->indicate_seq
+ 1)%4096;
3699 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__
, __LINE__
,
3700 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
);
3703 if(retval
!= _SUCCESS
){
3704 #ifdef DBG_RX_DROP_FRAME
3705 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__
);
3717 _enter_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3719 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
,
3720 ("recv_indicatepkt_reorder: indicate=%d seq=%d\n",
3721 preorder_ctrl
->indicate_seq
, pattrib
->seq_num
));
3723 //s2. check if winstart_b(indicate_seq) needs to been updated
3724 if(!check_indicate_seq(preorder_ctrl
, pattrib
->seq_num
))
3726 //pHTInfo->RxReorderDropCounter++;
3727 //ReturnRFDList(Adapter, pRfd);
3728 //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("RxReorderIndicatePacket() ==> Packet Drop!!\n"));
3729 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3732 #ifdef DBG_RX_DROP_FRAME
3733 DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __FUNCTION__
);
3736 rtw_recv_indicatepkt(padapter
, prframe
);
3738 _exit_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3747 //s3. Insert all packet into Reorder Queue to maintain its ordering.
3748 if(!enqueue_reorder_recvframe(preorder_ctrl
, prframe
))
3750 //DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n");
3751 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3753 #ifdef DBG_RX_DROP_FRAME
3754 DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __FUNCTION__
);
3761 // Indication process.
3762 // After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets
3763 // with the SeqNum smaller than latest WinStart and buffer other packets.
3765 // For Rx Reorder condition:
3766 // 1. All packets with SeqNum smaller than WinStart => Indicate
3767 // 2. All packets with SeqNum larger than or equal to WinStart => Buffer it.
3770 //recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE);
3771 if(recv_indicatepkts_in_order(padapter
, preorder_ctrl
, _FALSE
)==_TRUE
)
3773 _set_timer(&preorder_ctrl
->reordering_ctrl_timer
, REORDER_WAIT_TIME
);
3774 _exit_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3778 _exit_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3779 _cancel_timer_ex(&preorder_ctrl
->reordering_ctrl_timer
);
3789 _exit_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3795 void rtw_reordering_ctrl_timeout_handler(void *pcontext
)
3798 struct recv_reorder_ctrl
*preorder_ctrl
= (struct recv_reorder_ctrl
*)pcontext
;
3799 _adapter
*padapter
= preorder_ctrl
->padapter
;
3800 _queue
*ppending_recvframe_queue
= &preorder_ctrl
->pending_recvframe_queue
;
3803 if(padapter
->bDriverStopped
||padapter
->bSurpriseRemoved
)
3808 //DBG_871X("+rtw_reordering_ctrl_timeout_handler()=>\n");
3810 _enter_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3812 if(recv_indicatepkts_in_order(padapter
, preorder_ctrl
, _TRUE
)==_TRUE
)
3814 _set_timer(&preorder_ctrl
->reordering_ctrl_timer
, REORDER_WAIT_TIME
);
3817 _exit_critical_bh(&ppending_recvframe_queue
->lock
, &irql
);
3821 int process_recv_indicatepkts(_adapter
*padapter
, union recv_frame
*prframe
);
3822 int process_recv_indicatepkts(_adapter
*padapter
, union recv_frame
*prframe
)
3824 int retval
= _SUCCESS
;
3825 //struct recv_priv *precvpriv = &padapter->recvpriv;
3826 //struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib;
3827 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3829 struct sta_info
*psta
= prframe
->u
.hdr
.psta
;
3830 #endif //CONFIG_TDLS
3832 #ifdef CONFIG_80211N_HT
3834 struct ht_priv
*phtpriv
= &pmlmepriv
->htpriv
;
3837 if( (phtpriv
->ht_option
==_TRUE
) ||
3838 ((psta
->tdls_sta_state
& TDLS_LINKED_STATE
) &&
3839 (psta
->htpriv
.ht_option
==_TRUE
) &&
3840 (psta
->htpriv
.ampdu_enable
==_TRUE
))) //B/G/N Mode
3842 if(phtpriv
->ht_option
==_TRUE
) //B/G/N Mode
3843 #endif //CONFIG_TDLS
3845 //prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority];
3847 if(recv_indicatepkt_reorder(padapter
, prframe
)!=_SUCCESS
)// including perform A-MPDU Rx Ordering Buffer Control
3849 #ifdef DBG_RX_DROP_FRAME
3850 DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __FUNCTION__
);
3853 if ((padapter
->bDriverStopped
== _FALSE
) &&
3854 (padapter
->bSurpriseRemoved
== _FALSE
))
3864 retval
=wlanhdr_to_ethhdr (prframe
);
3865 if(retval
!= _SUCCESS
)
3867 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("wlanhdr_to_ethhdr: drop pkt \n"));
3868 #ifdef DBG_RX_DROP_FRAME
3869 DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __FUNCTION__
);
3874 if ((padapter
->bDriverStopped
==_FALSE
)&&( padapter
->bSurpriseRemoved
==_FALSE
))
3876 //indicate this recv_frame
3877 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n" ));
3878 rtw_recv_indicatepkt(padapter
, prframe
);
3884 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n" ));
3886 RT_TRACE(_module_rtl871x_recv_c_
, _drv_notice_
, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
3897 static int recv_func_prehandle(_adapter
*padapter
, union recv_frame
*rframe
)
3900 struct rx_pkt_attrib
*pattrib
= &rframe
->u
.hdr
.attrib
;
3901 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
3902 _queue
*pfree_recv_queue
= &padapter
->recvpriv
.free_recv_queue
;
3904 #ifdef CONFIG_MP_INCLUDED
3905 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3906 #endif //CONFIG_MP_INCLUDED
3908 #ifdef CONFIG_MP_INCLUDED
3909 if ((check_fwstate(pmlmepriv
, WIFI_MP_STATE
) == _TRUE
))//&&(padapter->mppriv.check_mp_pkt == 0))
3911 if (pattrib
->crc_err
== 1)
3912 padapter
->mppriv
.rx_crcerrpktcount
++;
3914 padapter
->mppriv
.rx_pktcount
++;
3916 if (check_fwstate(pmlmepriv
, WIFI_MP_LPBK_STATE
) == _FALSE
) {
3917 RT_TRACE(_module_rtl871x_recv_c_
, _drv_alert_
, ("MP - Not in loopback mode , drop pkt \n"));
3919 rtw_free_recvframe(rframe
, pfree_recv_queue
);//free this recv_frame
3925 //check the frame crtl field and decache
3926 ret
= validate_recv_frame(padapter
, rframe
);
3927 if (ret
!= _SUCCESS
)
3929 RT_TRACE(_module_rtl871x_recv_c_
, _drv_info_
, ("recv_func: validate_recv_frame fail! drop pkt\n"));
3930 rtw_free_recvframe(rframe
, pfree_recv_queue
);//free this recv_frame
3938 static int recv_func_posthandle(_adapter
*padapter
, union recv_frame
*prframe
)
3941 union recv_frame
*orig_prframe
= prframe
;
3942 struct rx_pkt_attrib
*pattrib
= &prframe
->u
.hdr
.attrib
;
3943 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
3944 _queue
*pfree_recv_queue
= &padapter
->recvpriv
.free_recv_queue
;
3946 #ifdef CONFIG_MP_INCLUDED
3947 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
3948 #endif //CONFIG_MP_INCLUDED
3951 u8
*psnap_type
, *pcategory
;
3952 struct sta_info
*ptdls_sta
= NULL
;
3953 #endif //CONFIG_TDLS
3957 rtw_led_control(padapter
, LED_CTL_RX
);
3959 prframe
= decryptor(padapter
, prframe
);
3960 if (prframe
== NULL
) {
3961 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("decryptor: drop pkt\n"));
3962 #ifdef DBG_RX_DROP_FRAME
3963 DBG_871X("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __FUNCTION__
);
3966 goto _recv_data_drop
;
3970 if ( padapter
->adapter_type
== PRIMARY_ADAPTER
)
3975 u8
*ptr
= get_recvframe_data(prframe
);
3976 for(i
=0; i
<140;i
=i
+8)
3977 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:", *(ptr
+i
),
3978 *(ptr
+i
+1), *(ptr
+i
+2) ,*(ptr
+i
+3) ,*(ptr
+i
+4),*(ptr
+i
+5), *(ptr
+i
+6), *(ptr
+i
+7));
3983 #endif //RTK_DMP_PLATFORM
3987 psnap_type
= get_recvframe_data(orig_prframe
);
3988 psnap_type
+=pattrib
->hdrlen
+ pattrib
->iv_len
+SNAP_SIZE
;
3989 pcategory
= psnap_type
+ ETH_TYPE_LEN
+ PAYLOAD_TYPE_LEN
;
3991 if((_rtw_memcmp(psnap_type
, SNAP_ETH_TYPE_TDLS
, ETH_TYPE_LEN
)) &&
3992 ((*pcategory
==RTW_WLAN_CATEGORY_TDLS
) || (*pcategory
==RTW_WLAN_CATEGORY_P2P
))){
3993 ret
= OnTDLS(padapter
, prframe
); //all of functions will return _FAIL
3994 goto _exit_recv_func
;
3996 #endif //CONFIG_TDLS
3998 prframe
= recvframe_chk_defrag(padapter
, prframe
);
4000 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("recvframe_chk_defrag: drop pkt\n"));
4001 #ifdef DBG_RX_DROP_FRAME
4002 DBG_871X("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __FUNCTION__
);
4004 goto _recv_data_drop
;
4007 prframe
=portctrl(padapter
, prframe
);
4008 if (prframe
== NULL
) {
4009 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("portctrl: drop pkt \n"));
4010 #ifdef DBG_RX_DROP_FRAME
4011 DBG_871X("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __FUNCTION__
);
4014 goto _recv_data_drop
;
4018 if(padapter
->tdlsinfo
.setup_state
== TDLS_LINKED_STATE
)
4019 ptdls_sta
= rtw_get_stainfo(&padapter
->stapriv
, pattrib
->src
);
4020 count_rx_stats(padapter
, prframe
, ptdls_sta
);
4022 count_rx_stats(padapter
, prframe
, NULL
);
4023 #endif //CONFIG_TDLS
4025 #ifdef CONFIG_80211N_HT
4027 ret
= process_recv_indicatepkts(padapter
, prframe
);
4028 if (ret
!= _SUCCESS
)
4030 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("recv_func: process_recv_indicatepkts fail! \n"));
4031 #ifdef DBG_RX_DROP_FRAME
4032 DBG_871X("DBG_RX_DROP_FRAME %s recv_func: process_recv_indicatepkts fail!\n", __FUNCTION__
);
4034 rtw_free_recvframe(orig_prframe
, pfree_recv_queue
);//free this recv_frame
4035 goto _recv_data_drop
;
4038 #else // CONFIG_80211N_HT
4040 if (!pattrib
->amsdu
)
4042 ret
= wlanhdr_to_ethhdr (prframe
);
4043 if (ret
!= _SUCCESS
)
4045 RT_TRACE(_module_rtl871x_recv_c_
,_drv_err_
,("wlanhdr_to_ethhdr: drop pkt \n"));
4046 #ifdef DBG_RX_DROP_FRAME
4047 DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr: drop pkt\n", __FUNCTION__
);
4049 rtw_free_recvframe(orig_prframe
, pfree_recv_queue
);//free this recv_frame
4050 goto _recv_data_drop
;
4053 if ((padapter
->bDriverStopped
== _FALSE
) && (padapter
->bSurpriseRemoved
== _FALSE
))
4055 RT_TRACE(_module_rtl871x_recv_c_
, _drv_alert_
, ("@@@@ recv_func: recv_func rtw_recv_indicatepkt\n" ));
4056 //indicate this recv_frame
4057 ret
= rtw_recv_indicatepkt(padapter
, prframe
);
4058 if (ret
!= _SUCCESS
)
4060 #ifdef DBG_RX_DROP_FRAME
4061 DBG_871X("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__
);
4063 goto _recv_data_drop
;
4068 RT_TRACE(_module_rtl871x_recv_c_
, _drv_alert_
, ("@@@@ recv_func: rtw_free_recvframe\n" ));
4069 RT_TRACE(_module_rtl871x_recv_c_
, _drv_debug_
, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
));
4070 #ifdef DBG_RX_DROP_FRAME
4071 DBG_871X("DBG_RX_DROP_FRAME %s ecv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", __FUNCTION__
,
4072 padapter
->bDriverStopped
, padapter
->bSurpriseRemoved
);
4075 rtw_free_recvframe(orig_prframe
, pfree_recv_queue
); //free this recv_frame
4079 else if(pattrib
->amsdu
==1)
4082 ret
= amsdu_to_msdu(padapter
, prframe
);
4085 #ifdef DBG_RX_DROP_FRAME
4086 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__
);
4088 rtw_free_recvframe(orig_prframe
, pfree_recv_queue
);
4089 goto _recv_data_drop
;
4094 #ifdef DBG_RX_DROP_FRAME
4095 DBG_871X("DBG_RX_DROP_FRAME %s what is this condition??\n", __FUNCTION__
);
4097 goto _recv_data_drop
;
4099 #endif // CONFIG_80211N_HT
4105 precvpriv
->rx_drop
++;
4110 static int recv_func(_adapter
*padapter
, union recv_frame
*rframe
)
4113 struct rx_pkt_attrib
*prxattrib
= &rframe
->u
.hdr
.attrib
;
4114 struct recv_priv
*recvpriv
= &padapter
->recvpriv
;
4115 struct security_priv
*psecuritypriv
=&padapter
->securitypriv
;
4116 struct mlme_priv
*mlmepriv
= &padapter
->mlmepriv
;
4118 /* check if need to handle uc_swdec_pending_queue*/
4119 if (check_fwstate(mlmepriv
, WIFI_STATION_STATE
) && psecuritypriv
->busetkipkey
)
4121 union recv_frame
*pending_frame
;
4124 while((pending_frame
=rtw_alloc_recvframe(&padapter
->recvpriv
.uc_swdec_pending_queue
))) {
4125 if (recv_func_posthandle(padapter
, pending_frame
) == _SUCCESS
)
4126 DBG_871X("%s: dequeue uc_swdec_pending_queue\n", __func__
);
4130 ret
= recv_func_prehandle(padapter
, rframe
);
4132 if(ret
== _SUCCESS
) {
4134 /* check if need to enqueue into uc_swdec_pending_queue*/
4135 if (check_fwstate(mlmepriv
, WIFI_STATION_STATE
) &&
4136 !IS_MCAST(prxattrib
->ra
) && prxattrib
->encrypt
>0 &&
4137 (prxattrib
->bdecrypted
== 0 ||psecuritypriv
->sw_decrypt
== _TRUE
) &&
4138 !is_wep_enc(psecuritypriv
->dot11PrivacyAlgrthm
) &&
4139 !psecuritypriv
->busetkipkey
) {
4140 rtw_enqueue_recvframe(rframe
, &padapter
->recvpriv
.uc_swdec_pending_queue
);
4141 DBG_871X("%s: no key, enqueue uc_swdec_pending_queue\n", __func__
);
4145 ret
= recv_func_posthandle(padapter
, rframe
);
4153 s32
rtw_recv_entry(union recv_frame
*precvframe
)
4156 struct recv_priv
*precvpriv
;
4161 // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("+rtw_recv_entry\n"));
4163 padapter
= precvframe
->u
.hdr
.adapter
;
4165 precvpriv
= &padapter
->recvpriv
;
4168 if ((ret
= recv_func(padapter
, precvframe
)) == _FAIL
)
4170 RT_TRACE(_module_rtl871x_recv_c_
,_drv_info_
,("rtw_recv_entry: recv_func return fail!!!\n"));
4171 goto _recv_entry_drop
;
4175 precvpriv
->rx_pkts
++;
4183 #ifdef CONFIG_MP_INCLUDED
4184 padapter
->mppriv
.rx_pktloss
= precvpriv
->rx_drop
;
4187 //RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("_recv_entry_drop\n"));
4194 #ifdef CONFIG_NEW_SIGNAL_STAT_PROCESS
4195 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS
){
4196 _adapter
*adapter
= (_adapter
*)FunctionContext
;
4197 struct recv_priv
*recvpriv
= &adapter
->recvpriv
;
4200 u8 avg_signal_strength
= 0;
4201 u8 avg_signal_qual
= 0;
4202 u32 num_signal_strength
= 0;
4203 u32 num_signal_qual
= 0;
4204 u8 _alpha
= 3; // this value is based on converging_constant = 5000 and sampling_interval = 1000
4206 if(adapter
->recvpriv
.is_signal_dbg
) {
4207 //update the user specific value, signal_strength_dbg, to signal_strength, rssi
4208 adapter
->recvpriv
.signal_strength
= adapter
->recvpriv
.signal_strength_dbg
;
4209 adapter
->recvpriv
.rssi
=(s8
)translate_percentage_to_dbm((u8
)adapter
->recvpriv
.signal_strength_dbg
);
4212 if(recvpriv
->signal_strength_data
.update_req
== 0) {// update_req is clear, means we got rx
4213 avg_signal_strength
= recvpriv
->signal_strength_data
.avg_val
;
4214 num_signal_strength
= recvpriv
->signal_strength_data
.total_num
;
4215 // after avg_vals are accquired, we can re-stat the signal values
4216 recvpriv
->signal_strength_data
.update_req
= 1;
4219 if(recvpriv
->signal_qual_data
.update_req
== 0) {// update_req is clear, means we got rx
4220 avg_signal_qual
= recvpriv
->signal_qual_data
.avg_val
;
4221 num_signal_qual
= recvpriv
->signal_qual_data
.total_num
;
4222 // after avg_vals are accquired, we can re-stat the signal values
4223 recvpriv
->signal_qual_data
.update_req
= 1;
4226 if (num_signal_strength
== 0) {
4227 if (rtw_get_on_cur_ch_time(adapter
) == 0
4228 || rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter
)) < 2 * adapter
->mlmeextpriv
.mlmext_info
.bcn_interval
4234 if(check_fwstate(&adapter
->mlmepriv
, _FW_UNDER_SURVEY
) == _TRUE
4235 || check_fwstate(&adapter
->mlmepriv
, _FW_LINKED
) == _FALSE
4240 #ifdef CONFIG_CONCURRENT_MODE
4241 if (check_buddy_fwstate(adapter
, _FW_UNDER_SURVEY
) == _TRUE
)
4245 //update value of signal_strength, rssi, signal_qual
4246 tmp_s
= (avg_signal_strength
+(_alpha
-1)*recvpriv
->signal_strength
);
4248 tmp_s
= tmp_s
/_alpha
+ 1;
4250 tmp_s
= tmp_s
/_alpha
;
4254 tmp_q
= (avg_signal_qual
+(_alpha
-1)*recvpriv
->signal_qual
);
4256 tmp_q
= tmp_q
/_alpha
+ 1;
4258 tmp_q
= tmp_q
/_alpha
;
4262 recvpriv
->signal_strength
= tmp_s
;
4263 recvpriv
->rssi
= (s8
)translate_percentage_to_dbm(tmp_s
);
4264 recvpriv
->signal_qual
= tmp_q
;
4266 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1
4267 DBG_871X(FUNC_ADPT_FMT
" signal_strength:%3u, rssi:%3d, signal_qual:%3u"
4268 ", num_signal_strength:%u, num_signal_qual:%u"
4271 , FUNC_ADPT_ARG(adapter
)
4272 , recvpriv
->signal_strength
4274 , recvpriv
->signal_qual
4275 , num_signal_strength
, num_signal_qual
4276 , rtw_get_on_cur_ch_time(adapter
) ? rtw_get_passing_time_ms(rtw_get_on_cur_ch_time(adapter
)) : 0
4282 rtw_set_signal_stat_timer(recvpriv
);
4285 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS