]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/net/wireless/realtek/rtl8192cu/core/rtw_recv.c
net: Fix rtl8192cu build errors on other platforms
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / realtek / rtl8192cu / core / rtw_recv.c
1 /******************************************************************************
2 *
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * 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
17 *
18 *
19 ******************************************************************************/
20 #define _RTW_RECV_C_
21 #include <drv_conf.h>
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <recv_osdep.h>
25 #include <mlme_osdep.h>
26 #include <ip.h>
27 #include <if_ether.h>
28 #include <ethernet.h>
29
30 #ifdef CONFIG_USB_HCI
31 #include <usb_ops.h>
32 #endif
33
34 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
35
36 #error "Shall be Linux or Windows, but not both!\n"
37
38 #endif
39
40 #include <wifi.h>
41 #include <circ_buf.h>
42
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
46
47
48 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
49 {
50
51
52 _func_enter_;
53
54 _rtw_memset((u8 *)psta_recvpriv, 0, sizeof (struct sta_recv_priv));
55
56 _rtw_spinlock_init(&psta_recvpriv->lock);
57
58 //for(i=0; i<MAX_RX_NUMBLKS; i++)
59 // _rtw_init_queue(&psta_recvpriv->blk_strms[i]);
60
61 _rtw_init_queue(&psta_recvpriv->defrag_q);
62
63 _func_exit_;
64
65 }
66
67 sint _rtw_init_recv_priv(struct recv_priv *precvpriv, _adapter *padapter)
68 {
69 sint i;
70
71 union recv_frame *precvframe;
72
73 sint res=_SUCCESS;
74
75 _func_enter_;
76
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));
79
80 _rtw_spinlock_init(&precvpriv->lock);
81
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);
85
86 precvpriv->adapter = padapter;
87
88 precvpriv->free_recvframe_cnt = NR_RECVFRAME;
89
90 rtw_os_recv_resource_init(precvpriv, padapter);
91
92 precvpriv->pallocated_frame_buf = rtw_zvmalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
93
94 if(precvpriv->pallocated_frame_buf==NULL){
95 res= _FAIL;
96 goto exit;
97 }
98 //_rtw_memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
99
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));
103
104 precvframe = (union recv_frame*) precvpriv->precv_frame_buf;
105
106
107 for(i=0; i < NR_RECVFRAME ; i++)
108 {
109 _rtw_init_listhead(&(precvframe->u.list));
110
111 rtw_list_insert_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue));
112
113 res = rtw_os_recv_resource_alloc(padapter, precvframe);
114
115 precvframe->u.hdr.adapter =padapter;
116 precvframe++;
117
118 }
119
120 #ifdef CONFIG_USB_HCI
121
122 precvpriv->rx_pending_cnt=1;
123
124 _rtw_init_sema(&precvpriv->allrxreturnevt, 0);
125
126 #endif
127
128 res = rtw_hal_init_recv_priv(padapter);
129
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;
134
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);
140 #endif
141
142 precvpriv->signal_stat_sampling_interval = 1000; //ms
143 //precvpriv->signal_stat_converging_constant = 5000; //ms
144
145 rtw_set_signal_stat_timer(precvpriv);
146 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS
147
148 exit:
149
150 _func_exit_;
151
152 return res;
153
154 }
155
156 void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv);
157 void rtw_mfree_recv_priv_lock(struct recv_priv *precvpriv)
158 {
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);
163 #endif
164
165 _rtw_spinlock_free(&precvpriv->free_recv_queue.lock);
166 _rtw_spinlock_free(&precvpriv->recv_pending_queue.lock);
167
168 _rtw_spinlock_free(&precvpriv->free_recv_buf_queue.lock);
169
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
173 }
174
175 void _rtw_free_recv_priv (struct recv_priv *precvpriv)
176 {
177 _adapter *padapter = precvpriv->adapter;
178
179 _func_enter_;
180
181 rtw_free_uc_swdec_pending_queue(padapter);
182
183 rtw_mfree_recv_priv_lock(precvpriv);
184
185 rtw_os_recv_resource_free(precvpriv);
186
187 if(precvpriv->pallocated_frame_buf) {
188 rtw_vmfree(precvpriv->pallocated_frame_buf, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
189 }
190
191 rtw_hal_free_recv_priv(padapter);
192
193 _func_exit_;
194
195 }
196
197 union recv_frame *_rtw_alloc_recvframe (_queue *pfree_recv_queue)
198 {
199
200 union recv_frame *precvframe;
201 _list *plist, *phead;
202 _adapter *padapter;
203 struct recv_priv *precvpriv;
204 _func_enter_;
205
206 if(_rtw_queue_empty(pfree_recv_queue) == _TRUE)
207 {
208 precvframe = NULL;
209 }
210 else
211 {
212 phead = get_list_head(pfree_recv_queue);
213
214 plist = get_next(phead);
215
216 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
217
218 rtw_list_delete(&precvframe->u.hdr.list);
219 padapter=precvframe->u.hdr.adapter;
220 if(padapter !=NULL){
221 precvpriv=&padapter->recvpriv;
222 if(pfree_recv_queue == &precvpriv->free_recv_queue)
223 precvpriv->free_recvframe_cnt--;
224 }
225 }
226
227 _func_exit_;
228
229 return precvframe;
230
231 }
232
233 union recv_frame *rtw_alloc_recvframe (_queue *pfree_recv_queue)
234 {
235 _irqL irqL;
236 union recv_frame *precvframe;
237
238 _enter_critical_bh(&pfree_recv_queue->lock, &irqL);
239
240 precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
241
242 _exit_critical_bh(&pfree_recv_queue->lock, &irqL);
243
244 return precvframe;
245 }
246
247 void rtw_init_recvframe(union recv_frame *precvframe, struct recv_priv *precvpriv)
248 {
249 /* Perry: This can be removed */
250 _rtw_init_listhead(&precvframe->u.hdr.list);
251
252 precvframe->u.hdr.len=0;
253 }
254
255 int rtw_free_recvframe(union recv_frame *precvframe, _queue *pfree_recv_queue)
256 {
257 _irqL irqL;
258 _adapter *padapter=precvframe->u.hdr.adapter;
259 struct recv_priv *precvpriv = &padapter->recvpriv;
260
261 _func_enter_;
262
263 #ifdef CONFIG_CONCURRENT_MODE
264 if(padapter->adapter_type > PRIMARY_ADAPTER)
265 {
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;
270 }
271 #endif
272
273
274 #ifdef PLATFORM_WINDOWS
275 rtw_os_read_port(padapter, precvframe->u.hdr.precvbuf);
276 #endif
277
278 #if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
279
280 if(precvframe->u.hdr.pkt)
281 {
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;
288 }
289
290 #endif //defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD)
291
292 _enter_critical_bh(&pfree_recv_queue->lock, &irqL);
293
294 rtw_list_delete(&(precvframe->u.hdr.list));
295
296 rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue));
297
298 if(padapter !=NULL){
299 if(pfree_recv_queue == &precvpriv->free_recv_queue)
300 precvpriv->free_recvframe_cnt++;
301 }
302
303 _exit_critical_bh(&pfree_recv_queue->lock, &irqL);
304
305 _func_exit_;
306
307 return _SUCCESS;
308
309 }
310
311
312
313
314 sint _rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
315 {
316
317 _adapter *padapter=precvframe->u.hdr.adapter;
318 struct recv_priv *precvpriv = &padapter->recvpriv;
319
320 _func_enter_;
321
322 //_rtw_init_listhead(&(precvframe->u.hdr.list));
323 rtw_list_delete(&(precvframe->u.hdr.list));
324
325
326 rtw_list_insert_tail(&(precvframe->u.hdr.list), get_list_head(queue));
327
328 if (padapter != NULL) {
329 if (queue == &precvpriv->free_recv_queue)
330 precvpriv->free_recvframe_cnt++;
331 }
332
333 _func_exit_;
334
335 return _SUCCESS;
336 }
337
338 sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
339 {
340 sint ret;
341 _irqL irqL;
342
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);
348
349 return ret;
350 }
351
352 /*
353 sint rtw_enqueue_recvframe(union recv_frame *precvframe, _queue *queue)
354 {
355 return rtw_free_recvframe(precvframe, queue);
356 }
357 */
358
359
360
361
362 /*
363 caller : defrag ; recvframe_chk_defrag in recv_thread (passive)
364 pframequeue: defrag_queue : will be accessed in recv_thread (passive)
365
366 using spinlock to protect
367
368 */
369
370 void rtw_free_recvframe_queue(_queue *pframequeue, _queue *pfree_recv_queue)
371 {
372 union recv_frame *precvframe;
373 _list *plist, *phead;
374
375 _func_enter_;
376 _rtw_spinlock(&pframequeue->lock);
377
378 phead = get_list_head(pframequeue);
379 plist = get_next(phead);
380
381 while(rtw_end_of_queue_search(phead, plist) == _FALSE)
382 {
383 precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
384
385 plist = get_next(plist);
386
387 //rtw_list_delete(&precvframe->u.hdr.list); // will do this in rtw_free_recvframe()
388
389 rtw_free_recvframe(precvframe, pfree_recv_queue);
390 }
391
392 _rtw_spinunlock(&pframequeue->lock);
393
394 _func_exit_;
395
396 }
397
398 u32 rtw_free_uc_swdec_pending_queue(_adapter *adapter)
399 {
400 u32 cnt = 0;
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__);
405 cnt++;
406 }
407
408 return cnt;
409 }
410
411
412 sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, _queue *queue)
413 {
414 _irqL irqL;
415
416 _enter_critical(&queue->lock, &irqL);
417
418 rtw_list_delete(&precvbuf->list);
419 rtw_list_insert_head(&precvbuf->list, get_list_head(queue));
420
421 _exit_critical(&queue->lock, &irqL);
422
423 return _SUCCESS;
424 }
425
426 sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, _queue *queue)
427 {
428 _irqL irqL;
429
430 _enter_critical(&queue->lock, &irqL);
431
432 rtw_list_delete(&precvbuf->list);
433
434 rtw_list_insert_tail(&precvbuf->list, get_list_head(queue));
435
436 _exit_critical(&queue->lock, &irqL);
437
438
439 return _SUCCESS;
440
441 }
442
443 struct recv_buf *rtw_dequeue_recvbuf (_queue *queue)
444 {
445 _irqL irqL;
446 struct recv_buf *precvbuf;
447 _list *plist, *phead;
448
449 _enter_critical(&queue->lock, &irqL);
450
451 if(_rtw_queue_empty(queue) == _TRUE)
452 {
453 precvbuf = NULL;
454 }
455 else
456 {
457 phead = get_list_head(queue);
458
459 plist = get_next(phead);
460
461 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list);
462
463 rtw_list_delete(&precvbuf->list);
464
465 }
466
467 _exit_critical(&queue->lock, &irqL);
468
469
470 return precvbuf;
471
472 }
473
474 sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe);
475 sint recvframe_chkmic(_adapter *adapter, union recv_frame *precvframe){
476
477 sint i,res=_SUCCESS;
478 u32 datalen;
479 u8 miccode[8];
480 u8 bmic_err=_FALSE,brpt_micerror = _TRUE;
481 u8 *pframe, *payload,*pframemic;
482 u8 *mickey;
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;
487
488 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
489 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
490 _func_enter_;
491
492 stainfo=rtw_get_stainfo(&adapter->stapriv ,&prxattrib->ta[0]);
493
494 if(prxattrib->encrypt ==_TKIP_)
495 {
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]));
499
500 //calculate mic code
501 if(stainfo!= NULL)
502 {
503 if(IS_MCAST(prxattrib->ra))
504 {
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];
509
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);
513
514 if(psecuritypriv->binstallGrpkey==_FALSE)
515 {
516 res=_FAIL;
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");
519 goto exit;
520 }
521 }
522 else{
523 mickey=&stainfo->dot11tkiprxmickey.skey[0];
524 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("\n recvframe_chkmic: unicast key \n"));
525 }
526
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;
530
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));
532
533 //rtw_seccalctkipmic(&stainfo->dot11tkiprxmickey.skey[0],pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data
534
535 rtw_seccalctkipmic(mickey,pframe,payload, datalen ,&miccode[0],(unsigned char)prxattrib->priority); //care the length of the data
536
537 pframemic=payload+datalen;
538
539 bmic_err=_FALSE;
540
541 for(i=0;i<8;i++){
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)));
544 bmic_err=_TRUE;
545 }
546 }
547
548
549 if(bmic_err==_TRUE){
550
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)));
555
556 {
557 uint i;
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)));
565 }
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));
568 }
569
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));
573
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;
578
579 if(brpt_micerror == _TRUE)
580 {
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);
584 }
585
586 res=_FAIL;
587
588 }
589 else{
590 //mic checked ok
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"));
594 }
595 }
596
597 }
598 else
599 {
600 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic: rtw_get_stainfo==NULL!!!\n"));
601 }
602
603 recvframe_pull_tail(precvframe, 8);
604
605 }
606
607 exit:
608
609 _func_exit_;
610
611 return res;
612
613 }
614
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)
618 {
619
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;
623 u32 res=_SUCCESS;
624 _func_enter_;
625
626 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("prxstat->decrypted=%x prxattrib->encrypt = 0x%03x\n",prxattrib->bdecrypted,prxattrib->encrypt));
627
628 if(prxattrib->encrypt>0)
629 {
630 u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen;
631 prxattrib->key_index = ( ((iv[3])>>6)&0x3) ;
632
633 if(prxattrib->key_index > WEP_KEYS)
634 {
635 DBG_871X("prxattrib->key_index(%d) > WEP_KEYS \n", prxattrib->key_index);
636
637 switch(prxattrib->encrypt){
638 case _WEP40_:
639 case _WEP104_:
640 prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
641 break;
642 case _TKIP_:
643 case _AES_:
644 default:
645 prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
646 break;
647 }
648 }
649 }
650
651 if((prxattrib->encrypt>0) && ((prxattrib->bdecrypted==0) ||(psecuritypriv->sw_decrypt==_TRUE)))
652 {
653
654 #ifdef CONFIG_CONCURRENT_MODE
655 if(!IS_MCAST(prxattrib->ra))//bc/mc packets use sw decryption for concurrent mode
656 #endif
657 psecuritypriv->hw_decrypted=_FALSE;
658
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);
662 #endif
663
664 switch(prxattrib->encrypt){
665 case _WEP40_:
666 case _WEP104_:
667 rtw_wep_decrypt(padapter, (u8 *)precv_frame);
668 break;
669 case _TKIP_:
670 res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
671 break;
672 case _AES_:
673 res = rtw_aes_decrypt(padapter, (u8 * )precv_frame);
674 break;
675 default:
676 break;
677 }
678 }
679 else if(prxattrib->bdecrypted==1
680 && prxattrib->encrypt >0
681 && (psecuritypriv->busetkipkey==1 || prxattrib->encrypt !=_TKIP_ )
682 )
683 {
684 #if 0
685 if((prxstat->icv==1)&&(prxattrib->encrypt!=_AES_))
686 {
687 psecuritypriv->hw_decrypted=_FALSE;
688
689 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("psecuritypriv->hw_decrypted=_FALSE"));
690
691 rtw_free_recvframe(precv_frame, &padapter->recvpriv.free_recv_queue);
692
693 return_packet=NULL;
694
695 }
696 else
697 #endif
698 {
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);
703 #endif
704
705 }
706 }
707 else {
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);
711 #endif
712 }
713
714 if(res == _FAIL)
715 {
716 rtw_free_recvframe(return_packet,&padapter->recvpriv.free_recv_queue);
717 return_packet = NULL;
718
719 }
720 //recvframe_chkmic(adapter, precv_frame); //move to recvframme_defrag function
721
722 _func_exit_;
723
724 return return_packet;
725
726 }
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)
730 {
731 u8 *psta_addr,*ptr;
732 uint auth_alg;
733 struct recv_frame_hdr *pfhdr;
734 struct sta_info * psta;
735 struct sta_priv *pstapriv ;
736 union recv_frame * prtnframe;
737 u16 ether_type=0;
738 u16 eapol_type = 0x888e;//for Funia BD's WPA issue
739 struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
740
741 _func_enter_;
742
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);
748
749 auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
750
751 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:adapter->securitypriv.dot11AuthAlgrthm= 0x%d\n",adapter->securitypriv.dot11AuthAlgrthm));
752
753 if(auth_alg==2)
754 {
755 if ((psta!=NULL) && (psta->ieee8021x_blocked))
756 {
757 //blocked
758 //only accept EAPOL frame
759 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("########portctrl:psta->ieee8021x_blocked==1\n"));
760
761 prtnframe=precv_frame;
762
763 //get ether_type
764 ptr=ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
765 _rtw_memcpy(&ether_type,ptr, 2);
766 ether_type= ntohs((unsigned short )ether_type);
767
768 if (ether_type == eapol_type) {
769 prtnframe=precv_frame;
770 }
771 else {
772 //free this frame
773 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
774 prtnframe=NULL;
775 }
776 }
777 else
778 {
779 //allowed
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));
783
784 if(pattrib->bdecrypted==0)
785 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("portctrl:prxstat->decrypted=%x\n", pattrib->bdecrypted));
786
787 prtnframe=precv_frame;
788 //check is the EAPOL frame or not (Rekey)
789 if(ether_type == eapol_type){
790
791 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("########portctrl:ether_type == 0x888e\n"));
792 //check Rekey
793
794 prtnframe=precv_frame;
795 }
796 else{
797 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("########portctrl:ether_type = 0x%.4x\n",ether_type));
798 }
799 }
800 }
801 else
802 {
803 prtnframe=precv_frame;
804 }
805
806 _func_exit_;
807
808 return prtnframe;
809
810 }
811
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)
814 {
815 sint tid = precv_frame->u.hdr.attrib.priority;
816
817 u16 seq_ctrl = ( (precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) |
818 (precv_frame->u.hdr.attrib.frag_num & 0xf);
819
820 _func_enter_;
821
822 if(tid>15)
823 {
824 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl=0x%x, tid=0x%x\n", seq_ctrl, tid));
825
826 return _FAIL;
827 }
828
829 if(1)//if(bretry)
830 {
831 if(seq_ctrl == prxcache->tid_rxseq[tid])
832 {
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]));
834
835 return _FAIL;
836 }
837 }
838
839 prxcache->tid_rxseq[tid] = seq_ctrl;
840
841 _func_exit_;
842
843 return _SUCCESS;
844
845 }
846
847 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame);
848 void process_pwrbit_data(_adapter *padapter, union recv_frame *precv_frame)
849 {
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;
856
857 psta = rtw_get_stainfo(pstapriv, pattrib->src);
858
859 pwrbit = GetPwrMgt(ptr);
860
861 if(psta)
862 {
863 if(pwrbit)
864 {
865 if(!(psta->state & WIFI_SLEEP_STATE))
866 {
867 //psta->state |= WIFI_SLEEP_STATE;
868 //pstapriv->sta_dz_bitmap |= BIT(psta->aid);
869
870 stop_sta_xmit(padapter, psta);
871
872 //DBG_871X("to sleep, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap);
873 }
874 }
875 else
876 {
877 if(psta->state & WIFI_SLEEP_STATE)
878 {
879 //psta->state ^= WIFI_SLEEP_STATE;
880 //pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
881
882 wakeup_sta_to_xmit(padapter, psta);
883
884 //DBG_871X("to wakeup, sta_dz_bitmap=%x\n", pstapriv->sta_dz_bitmap);
885 }
886 }
887
888 }
889
890 #endif
891 }
892
893 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame);
894 void process_wmmps_data(_adapter *padapter, union recv_frame *precv_frame)
895 {
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;
900
901 psta = rtw_get_stainfo(pstapriv, pattrib->src);
902
903 if(!psta) return;
904
905 #ifdef CONFIG_TDLS
906 if( !(psta->tdls_sta_state & TDLS_LINKED_STATE ) )
907 {
908 #endif //CONFIG_TDLS
909
910 if(!psta->qos_option)
911 return;
912
913 if(!(psta->qos_info&0xf))
914 return;
915
916 #ifdef CONFIG_TDLS
917 }
918 #endif //CONFIG_TDLS
919
920 if(psta->state&WIFI_SLEEP_STATE)
921 {
922 u8 wmmps_ac=0;
923
924 switch(pattrib->priority)
925 {
926 case 1:
927 case 2:
928 wmmps_ac = psta->uapsd_bk&BIT(1);
929 break;
930 case 4:
931 case 5:
932 wmmps_ac = psta->uapsd_vi&BIT(1);
933 break;
934 case 6:
935 case 7:
936 wmmps_ac = psta->uapsd_vo&BIT(1);
937 break;
938 case 0:
939 case 3:
940 default:
941 wmmps_ac = psta->uapsd_be&BIT(1);
942 break;
943 }
944
945 if(wmmps_ac)
946 {
947 if(psta->sleepq_ac_len>0)
948 {
949 //process received triggered frame
950 xmit_delivery_enabled_frames(padapter, psta);
951 }
952 else
953 {
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);
956 }
957 }
958
959 }
960
961
962 #endif
963
964 }
965
966 #ifdef CONFIG_TDLS
967 sint OnTDLS(_adapter *adapter, union recv_frame *precv_frame)
968 {
969 struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
970 sint ret = _SUCCESS;
971 u8 *paction = get_recvframe_data(precv_frame);
972 u8 category_field = 1;
973 #ifdef CONFIG_WFD
974 u8 WFA_OUI[3] = { 0x50, 0x6f, 0x9a };
975 #endif //CONFIG_WFD
976 struct tdls_info *ptdlsinfo = &(adapter->tdlsinfo);
977
978 //point to action field
979 paction+=pattrib->hdrlen
980 + pattrib->iv_len
981 + SNAP_SIZE
982 + ETH_TYPE_LEN
983 + PAYLOAD_TYPE_LEN
984 + category_field;
985
986 if(ptdlsinfo->enable == 0)
987 {
988 DBG_871X("recv tdls frame, "
989 "but tdls haven't enabled\n");
990 ret = _FAIL;
991 return ret;
992 }
993
994 switch(*paction){
995 case TDLS_SETUP_REQUEST:
996 DBG_871X("recv tdls setup request frame\n");
997 ret=On_TDLS_Setup_Req(adapter, precv_frame);
998 break;
999 case TDLS_SETUP_RESPONSE:
1000 DBG_871X("recv tdls setup response frame\n");
1001 ret=On_TDLS_Setup_Rsp(adapter, precv_frame);
1002 break;
1003 case TDLS_SETUP_CONFIRM:
1004 DBG_871X("recv tdls setup confirm frame\n");
1005 ret=On_TDLS_Setup_Cfm(adapter, precv_frame);
1006 break;
1007 case TDLS_TEARDOWN:
1008 DBG_871X("recv tdls teardown, free sta_info\n");
1009 ret=On_TDLS_Teardown(adapter, precv_frame);
1010 break;
1011 case TDLS_DISCOVERY_REQUEST:
1012 DBG_871X("recv tdls discovery request frame\n");
1013 ret=On_TDLS_Dis_Req(adapter, precv_frame);
1014 break;
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);
1018 break;
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);
1022 break;
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);
1026 break;
1027 #ifdef CONFIG_WFD
1028 case 0x50: //First byte of WFA OUI
1029 if( _rtw_memcmp(WFA_OUI, (paction), 3) )
1030 {
1031 if( *(paction + 3) == 0x04) //Probe request frame
1032 {
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);
1037 }
1038 if( *(paction + 3) == 0x05) //Probe response frame
1039 {
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");
1043 }
1044 }
1045 break;
1046 #endif //CONFIG_WFD
1047 default:
1048 DBG_871X("receive TDLS frame but not supported\n");
1049 ret=_FAIL;
1050 break;
1051 }
1052
1053 exit:
1054 return ret;
1055
1056 }
1057 #endif //CONFIG_TDLS
1058
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)
1061 {
1062 int sz;
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;
1067
1068 sz = get_recvframe_len(prframe);
1069 precvpriv->rx_bytes += sz;
1070
1071 padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
1072
1073 if( (!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))){
1074 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
1075 }
1076
1077 if(sta)
1078 psta = sta;
1079 else
1080 psta = prframe->u.hdr.psta;
1081
1082 if(psta)
1083 {
1084 pstats = &psta->sta_stats;
1085
1086 pstats->rx_data_pkts++;
1087 pstats->rx_bytes += sz;
1088 }
1089
1090 }
1091
1092 sint sta2sta_data_frame(
1093 _adapter *adapter,
1094 union recv_frame *precv_frame,
1095 struct sta_info**psta
1096 );
1097 sint sta2sta_data_frame(
1098 _adapter *adapter,
1099 union recv_frame *precv_frame,
1100 struct sta_info**psta
1101 )
1102 {
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);
1112
1113 #ifdef CONFIG_TDLS
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
1119
1120 _func_enter_;
1121
1122 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == _TRUE) ||
1123 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == _TRUE))
1124 {
1125
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"));
1129 ret= _FAIL;
1130 goto exit;
1131 }
1132
1133 if( (!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast) ){
1134 ret= _FAIL;
1135 goto exit;
1136 }
1137
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)) ) {
1141 ret= _FAIL;
1142 goto exit;
1143 }
1144
1145 sta_addr = pattrib->src;
1146
1147 }
1148 else if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1149 {
1150 #ifdef CONFIG_TDLS
1151 //direct link data transfer
1152 if(ptdlsinfo->setup_state == TDLS_LINKED_STATE){
1153 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->src);
1154 if(ptdls_sta==NULL)
1155 {
1156 ret=_FAIL;
1157 goto exit;
1158 }
1159 else if(ptdls_sta->tdls_sta_state&TDLS_LINKED_STATE)
1160 {
1161 //drop QoS-SubType Data, including QoS NULL, excluding QoS-Data
1162 if( (GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE )== WIFI_QOS_DATA_TYPE)
1163 {
1164 if(GetFrameSubType(ptr)&(BIT(4)|BIT(5)|BIT(6)))
1165 {
1166 DBG_871X("drop QoS-Sybtype Data\n");
1167 ret= _FAIL;
1168 goto exit;
1169 }
1170 }
1171 // filter packets that SA is myself or multicast or broadcast
1172 if (_rtw_memcmp(myhwaddr, pattrib->src, ETH_ALEN)){
1173 ret= _FAIL;
1174 goto exit;
1175 }
1176 // da should be for me
1177 if((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN))&& (!bmcast))
1178 {
1179 ret= _FAIL;
1180 goto exit;
1181 }
1182 // check BSSID
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)) )
1186 {
1187 ret= _FAIL;
1188 goto exit;
1189 }
1190
1191 //process UAPSD tdls sta
1192 process_pwrbit_data(adapter, precv_frame);
1193
1194 // if NULL-frame, check pwrbit
1195 if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL)
1196 {
1197 //NULL-frame with pwrbit=1, buffer_STA should buffer frames for sleep_STA
1198 if(GetPwrMgt(ptr))
1199 {
1200 DBG_871X("TDLS: recv peer null frame with pwr bit 1\n");
1201 ptdls_sta->tdls_sta_state|=TDLS_PEER_SLEEP_STATE;
1202 }
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)
1206 {
1207 if((ptdls_sta->tdls_sta_state & TDLS_PEER_AT_OFF_STATE) != TDLS_PEER_AT_OFF_STATE)
1208 {
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);
1212 }
1213 }
1214
1215 ret= _FAIL;
1216 goto exit;
1217 }
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);
1221 goto exit;
1222 }
1223
1224 }
1225
1226 sta_addr = pattrib->src;
1227
1228 }
1229 else
1230 #endif //CONFIG_TDLS
1231 {
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) )
1234 {
1235 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("bssid != TA under STATION_MODE; drop pkt\n"));
1236 ret= _FAIL;
1237 goto exit;
1238 }
1239
1240 sta_addr = pattrib->bssid;
1241 }
1242 }
1243 else if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1244 {
1245 if (bmcast)
1246 {
1247 // For AP mode, if DA == MCAST, then BSSID should be also MCAST
1248 if (!IS_MCAST(pattrib->bssid)){
1249 ret= _FAIL;
1250 goto exit;
1251 }
1252 }
1253 else // not mc-frame
1254 {
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)) {
1257 ret= _FAIL;
1258 goto exit;
1259 }
1260
1261 sta_addr = pattrib->src;
1262 }
1263
1264 }
1265 else if(check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
1266 {
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);
1272
1273 sta_addr = mybssid;
1274 }
1275 else
1276 {
1277 ret = _FAIL;
1278 }
1279
1280
1281
1282 if(bmcast)
1283 *psta = rtw_get_bcmc_stainfo(adapter);
1284 else
1285 *psta = rtw_get_stainfo(pstapriv, sta_addr); // get ap_info
1286
1287 #ifdef CONFIG_TDLS
1288 if(ptdls_sta != NULL)
1289 *psta = ptdls_sta;
1290 #endif //CONFIG_TDLS
1291
1292
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++;
1298 #endif
1299 ret= _FAIL;
1300 goto exit;
1301 }
1302
1303 exit:
1304 _func_exit_;
1305 return ret;
1306
1307 }
1308
1309 sint ap2sta_data_frame(
1310 _adapter *adapter,
1311 union recv_frame *precv_frame,
1312 struct sta_info**psta );
1313 sint ap2sta_data_frame(
1314 _adapter *adapter,
1315 union recv_frame *precv_frame,
1316 struct sta_info**psta )
1317 {
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);
1326
1327 _func_enter_;
1328
1329 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
1330 && (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE
1331 || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == _TRUE )
1332 )
1333 {
1334
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));
1344 #endif
1345 ret= _FAIL;
1346 goto exit;
1347 }
1348
1349 // da should be for me
1350 if((!_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN))&& (!bmcast))
1351 {
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));
1356 #endif
1357 ret= _FAIL;
1358 goto exit;
1359 }
1360
1361
1362 // check BSSID
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)) )
1366 {
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 );
1374 #endif
1375
1376 if(!bmcast)
1377 {
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);
1380 }
1381
1382 ret= _FAIL;
1383 goto exit;
1384 }
1385
1386 if(bmcast)
1387 *psta = rtw_get_bcmc_stainfo(adapter);
1388 else
1389 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get ap_info
1390
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__);
1395 #endif
1396 ret= _FAIL;
1397 goto exit;
1398 }
1399
1400 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1401 }
1402
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;
1407 goto exit;
1408 }
1409
1410 }
1411 else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE) &&
1412 (check_fwstate(pmlmepriv, _FW_LINKED) == _TRUE) )
1413 {
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);
1419
1420 //
1421 _rtw_memcpy(pattrib->bssid, mybssid, ETH_ALEN);
1422
1423
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__);
1429 #endif
1430 ret= _FAIL;
1431 goto exit;
1432 }
1433
1434
1435 }
1436 else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1437 {
1438 /* Special case */
1439 ret = RTW_RX_HANDLED;
1440 goto exit;
1441 }
1442 else
1443 {
1444 if(_rtw_memcmp(myhwaddr, pattrib->dst, ETH_ALEN)&& (!bmcast))
1445 {
1446 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); // get sta_info
1447 if (*psta == NULL)
1448 {
1449 DBG_871X("issue_deauth to the ap=" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid));
1450
1451 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1452 }
1453 }
1454
1455 ret = _FAIL;
1456 #ifdef DBG_RX_DROP_FRAME
1457 DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __FUNCTION__, get_fwstate(pmlmepriv));
1458 #endif
1459 }
1460
1461 exit:
1462
1463 _func_exit_;
1464
1465 return ret;
1466
1467 }
1468
1469 sint sta2ap_data_frame(
1470 _adapter *adapter,
1471 union recv_frame *precv_frame,
1472 struct sta_info**psta );
1473 sint sta2ap_data_frame(
1474 _adapter *adapter,
1475 union recv_frame *precv_frame,
1476 struct sta_info**psta )
1477 {
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);
1483 sint ret=_SUCCESS;
1484
1485 _func_enter_;
1486
1487 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1488 {
1489 //For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR
1490 if(!_rtw_memcmp(pattrib->bssid, mybssid, ETH_ALEN))
1491 {
1492 ret= _FAIL;
1493 goto exit;
1494 }
1495
1496 *psta = rtw_get_stainfo(pstapriv, pattrib->src);
1497 if (*psta == NULL)
1498 {
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));
1501
1502 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1503
1504 ret = RTW_RX_HANDLED;
1505 goto exit;
1506 }
1507
1508 process_pwrbit_data(adapter, precv_frame);
1509
1510 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
1511 process_wmmps_data(adapter, precv_frame);
1512 }
1513
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;
1518 goto exit;
1519 }
1520 }
1521 else {
1522 u8 *myhwaddr = myid(&adapter->eeprompriv);
1523 if (!_rtw_memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
1524 ret = RTW_RX_HANDLED;
1525 goto exit;
1526 }
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;
1530 goto exit;
1531 }
1532
1533 exit:
1534
1535 _func_exit_;
1536
1537 return ret;
1538
1539 }
1540
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)
1543 {
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;
1549
1550 //DBG_871X("+validate_recv_ctrl_frame\n");
1551
1552 if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
1553 {
1554 return _FAIL;
1555 }
1556
1557 //receive the frames that ra(a1) is my address
1558 if (!_rtw_memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN))
1559 {
1560 return _FAIL;
1561 }
1562
1563 //only handle ps-poll
1564 if(GetFrameSubType(pframe) == WIFI_PSPOLL)
1565 {
1566 u16 aid;
1567 u8 wmmps_ac=0;
1568 struct sta_info *psta=NULL;
1569
1570 aid = GetAid(pframe);
1571 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
1572
1573 if((psta==NULL) || (psta->aid!=aid))
1574 {
1575 return _FAIL;
1576 }
1577
1578 //for rx pkt statistics
1579 psta->sta_stats.rx_ctrl_pkts++;
1580
1581 switch(pattrib->priority)
1582 {
1583 case 1:
1584 case 2:
1585 wmmps_ac = psta->uapsd_bk&BIT(0);
1586 break;
1587 case 4:
1588 case 5:
1589 wmmps_ac = psta->uapsd_vi&BIT(0);
1590 break;
1591 case 6:
1592 case 7:
1593 wmmps_ac = psta->uapsd_vo&BIT(0);
1594 break;
1595 case 0:
1596 case 3:
1597 default:
1598 wmmps_ac = psta->uapsd_be&BIT(0);
1599 break;
1600 }
1601
1602 if(wmmps_ac)
1603 return _FAIL;
1604
1605 if(psta->state & WIFI_STA_ALIVE_CHK_STATE)
1606 {
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;
1610 }
1611
1612 if((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid)))
1613 {
1614 _irqL irqL;
1615 _list *xmitframe_plist, *xmitframe_phead;
1616 struct xmit_frame *pxmitframe=NULL;
1617 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1618
1619 //_enter_critical_bh(&psta->sleep_q.lock, &irqL);
1620 _enter_critical_bh(&pxmitpriv->lock, &irqL);
1621
1622 xmitframe_phead = get_list_head(&psta->sleep_q);
1623 xmitframe_plist = get_next(xmitframe_phead);
1624
1625 if ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) == _FALSE)
1626 {
1627 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
1628
1629 xmitframe_plist = get_next(xmitframe_plist);
1630
1631 rtw_list_delete(&pxmitframe->list);
1632
1633 psta->sleepq_len--;
1634
1635 if(psta->sleepq_len>0)
1636 pxmitframe->attrib.mdata = 1;
1637 else
1638 pxmitframe->attrib.mdata = 0;
1639
1640 pxmitframe->attrib.triggered = 1;
1641
1642 //DBG_871X("handling ps-poll, q_len=%d, tim=%x\n", psta->sleepq_len, pstapriv->tim_bitmap);
1643
1644 #if 0
1645 _exit_critical_bh(&psta->sleep_q.lock, &irqL);
1646 if(rtw_hal_xmit(padapter, pxmitframe) == _TRUE)
1647 {
1648 rtw_os_xmit_complete(padapter, pxmitframe);
1649 }
1650 _enter_critical_bh(&psta->sleep_q.lock, &irqL);
1651 #endif
1652 rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
1653
1654 if(psta->sleepq_len==0)
1655 {
1656 pstapriv->tim_bitmap &= ~BIT(psta->aid);
1657
1658 //DBG_871X("after handling ps-poll, tim=%x\n", pstapriv->tim_bitmap);
1659
1660 //upate BCN for TIM IE
1661 //update_BCNTIM(padapter);
1662 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
1663 }
1664
1665 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
1666 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1667
1668 }
1669 else
1670 {
1671 //_exit_critical_bh(&psta->sleep_q.lock, &irqL);
1672 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1673
1674 //DBG_871X("no buffered packets to xmit\n");
1675 if(pstapriv->tim_bitmap&BIT(psta->aid))
1676 {
1677 if(psta->sleepq_len==0)
1678 {
1679 DBG_871X("no buffered packets to xmit\n");
1680
1681 //issue nulldata with More data bit = 0 to indicate we have no buffered packets
1682 issue_nulldata(padapter, psta->hwaddr, 0, 0, 0);
1683 }
1684 else
1685 {
1686 DBG_871X("error!psta->sleepq_len=%d\n", psta->sleepq_len);
1687 psta->sleepq_len=0;
1688 }
1689
1690 pstapriv->tim_bitmap &= ~BIT(psta->aid);
1691
1692 //upate BCN for TIM IE
1693 //update_BCNTIM(padapter);
1694 update_beacon(padapter, _TIM_IE_, NULL, _FALSE);
1695 }
1696
1697 }
1698
1699 }
1700
1701 }
1702
1703 #endif
1704
1705 return _FAIL;
1706
1707 }
1708
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)
1712 {
1713 //struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1714
1715 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n"));
1716
1717 #if 0
1718 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
1719 {
1720 #ifdef CONFIG_NATIVEAP_MLME
1721 mgt_dispatcher(padapter, precv_frame);
1722 #else
1723 rtw_hostapd_mlme_rx(padapter, precv_frame);
1724 #endif
1725 }
1726 else
1727 {
1728 mgt_dispatcher(padapter, precv_frame);
1729 }
1730 #endif
1731
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__));
1735 return _SUCCESS;
1736 }
1737
1738 {
1739 //for rx pkt statistics
1740 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data));
1741 if (psta) {
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++;
1753 else
1754 psta->sta_stats.rx_probersp_uo_pkts++;
1755 }
1756 }
1757 }
1758
1759 #ifdef CONFIG_INTEL_PROXIM
1760 if(padapter->proximity.proxim_on==_TRUE)
1761 {
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;
1766 pda = get_da(ptr);
1767 psa = get_sa(ptr);
1768 pbssid = get_hdr_bssid(ptr);
1769
1770
1771 _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
1772 _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
1773
1774 _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1775
1776 switch(pattrib->to_fr_ds)
1777 {
1778 case 0:
1779 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
1780 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
1781 break;
1782
1783 case 1:
1784 _rtw_memcpy(pattrib->ra, pda, ETH_ALEN);
1785 _rtw_memcpy(pattrib->ta, pbssid, ETH_ALEN);
1786 break;
1787
1788 case 2:
1789 _rtw_memcpy(pattrib->ra, pbssid, ETH_ALEN);
1790 _rtw_memcpy(pattrib->ta, psa, ETH_ALEN);
1791 break;
1792
1793 case 3:
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"));
1797 break;
1798
1799 default:
1800 break;
1801
1802 }
1803 pattrib->priority=0;
1804 pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24;
1805
1806 padapter->proximity.proxim_rx(padapter,precv_frame);
1807 }
1808 #endif
1809 mgt_dispatcher(padapter, precv_frame);
1810
1811 return _SUCCESS;
1812
1813 }
1814
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)
1817 {
1818 u8 bretry;
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;
1825 #ifdef CONFIG_TDLS
1826 struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
1827 #endif //CONFIG_TDLS
1828
1829 _func_enter_;
1830
1831 bretry = GetRetry(ptr);
1832 pda = get_da(ptr);
1833 psa = get_sa(ptr);
1834 pbssid = get_hdr_bssid(ptr);
1835
1836 if(pbssid == NULL){
1837 ret= _FAIL;
1838 goto exit;
1839 }
1840
1841 _rtw_memcpy(pattrib->dst, pda, ETH_ALEN);
1842 _rtw_memcpy(pattrib->src, psa, ETH_ALEN);
1843
1844 _rtw_memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1845
1846 switch(pattrib->to_fr_ds)
1847 {
1848 case 0:
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);
1852 break;
1853
1854 case 1:
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);
1858 break;
1859
1860 case 2:
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);
1864 break;
1865
1866 case 3:
1867 _rtw_memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1868 _rtw_memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1869 ret =_FAIL;
1870 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" case 3\n"));
1871 break;
1872
1873 default:
1874 ret =_FAIL;
1875 break;
1876
1877 }
1878
1879 if(ret ==_FAIL){
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);
1882 #endif
1883 goto exit;
1884 } else if (ret == RTW_RX_HANDLED) {
1885 goto exit;
1886 }
1887
1888
1889 if(psta==NULL){
1890 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,(" after to_fr_ds_chk; psta==NULL \n"));
1891 ret= _FAIL;
1892 goto exit;
1893 }
1894
1895 //psta->rssi = prxcmd->rssi;
1896 //psta->signal_quality= prxcmd->sq;
1897 precv_frame->u.hdr.psta = psta;
1898
1899
1900 pattrib->amsdu=0;
1901 pattrib->ack_policy = 0;
1902 //parsing QC field
1903 if(pattrib->qos == 1)
1904 {
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;
1909
1910 if(pattrib->priority!=0 && pattrib->priority!=3)
1911 {
1912 adapter->recvpriv.bIsAnyNonBEPkts = _TRUE;
1913 }
1914 }
1915 else
1916 {
1917 pattrib->priority=0;
1918 pattrib->hdrlen = pattrib->to_fr_ds==3 ? 30 : 24;
1919 }
1920
1921
1922 if(pattrib->order)//HT-CTRL 11n
1923 {
1924 pattrib->hdrlen += 4;
1925 }
1926
1927 precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1928
1929 // decache, drop duplicate recv packets
1930 if(recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL)
1931 {
1932 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("decache : drop pkt\n"));
1933 ret= _FAIL;
1934 goto exit;
1935 }
1936
1937 #if 0
1938 if(psta->tdls_sta_state & TDLS_LINKED_STATE )
1939 {
1940 if(psta->dot118021XPrivacy==_AES_)
1941 pattrib->encrypt=psta->dot118021XPrivacy;
1942 }
1943 #endif //CONFIG_TDLS
1944
1945 if(pattrib->privacy){
1946
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)));
1949
1950 #ifdef CONFIG_TDLS
1951 if((psta->tdls_sta_state & TDLS_LINKED_STATE) && (psta->dot118021XPrivacy==_AES_))
1952 {
1953 pattrib->encrypt=psta->dot118021XPrivacy;
1954 }
1955 else
1956 #endif //CONFIG_TDLS
1957 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra));
1958
1959 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n pattrib->encrypt=%d\n",pattrib->encrypt));
1960
1961 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1962 }
1963 else
1964 {
1965 pattrib->encrypt = 0;
1966 pattrib->iv_len = pattrib->icv_len = 0;
1967 }
1968
1969 exit:
1970
1971 _func_exit_;
1972
1973 return ret;
1974 }
1975
1976 #ifdef CONFIG_IEEE80211W
1977 static sint validate_80211w_mgmt(_adapter *adapter, union recv_frame *precv_frame)
1978 {
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;
1982 u8 type;
1983 u8 subtype;
1984
1985 type = GetFrameType(ptr);
1986 subtype = GetFrameSubType(ptr); //bit(7)~bit(2)
1987
1988 //only support station mode
1989 if(check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED)
1990 && adapter->securitypriv.binstallBIPkey == _TRUE)
1991 {
1992 //unicast management frame decrypt
1993 if(pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) &&
1994 (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION))
1995 {
1996 u8 *ppp, *mgmt_DATA;
1997 u32 data_len=0;
1998 ppp = GetAddr2Ptr(ptr);
1999
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)
2011 {
2012 DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __FUNCTION__);
2013 goto validate_80211w_fail;
2014 }
2015 /*//dump the packet content before decrypt
2016 {
2017 int pp;
2018 printk("pattrib->pktlen = %d =>", pattrib->pkt_len);
2019 for(pp=0;pp< pattrib->pkt_len; pp++)
2020 printk(" %02x ", ptr[pp]);
2021 printk("\n");
2022 }*/
2023
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
2033 {
2034 int pp;
2035 printk("after decryption pattrib->pktlen = %d @@=>", pattrib->pkt_len);
2036 for(pp=0;pp< pattrib->pkt_len; pp++)
2037 printk(" %02x ", ptr[pp]);
2038 printk("\n");
2039 }*/
2040 if(!precv_frame)
2041 {
2042 DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __FUNCTION__);
2043 goto validate_80211w_fail;
2044 }
2045 }
2046 else if(IS_MCAST(GetAddr1Ptr(ptr)) &&
2047 (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC))
2048 {
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)
2053 {
2054 //DBG_871X("802.11w BIP verify fail\n");
2055 goto validate_80211w_fail;
2056 }
2057 else if(BIP_ret == RTW_RX_HANDLED)
2058 {
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;
2063 }
2064 }//802.11w protect
2065 else
2066 {
2067 if(subtype == WIFI_ACTION)
2068 {
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)
2075 {
2076 DBG_871X("action frame category=%d should robust\n", ptr[WLAN_HDR_A3_LEN]);
2077 goto validate_80211w_fail;
2078 }
2079 }
2080 else if(subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)
2081 {
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;
2086 }
2087 }
2088 }
2089 return _SUCCESS;
2090
2091 validate_80211w_fail:
2092 return _FAIL;
2093
2094 }
2095 #endif //CONFIG_IEEE80211W
2096
2097 sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame);
2098 sint validate_recv_frame(_adapter *adapter, union recv_frame *precv_frame)
2099 {
2100 //shall check frame subtype, to / from ds, da, bssid
2101
2102 //then call check if rx seq/frag. duplicated.
2103
2104 u8 type;
2105 u8 subtype;
2106 sint retval = _SUCCESS;
2107
2108 struct rx_pkt_attrib *pattrib = & precv_frame->u.hdr.attrib;
2109
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;
2114 #endif
2115
2116 #ifdef CONFIG_TDLS
2117 struct tdls_info *ptdlsinfo = &adapter->tdlsinfo;
2118 #endif //CONFIG_TDLS
2119
2120 _func_enter_;
2121
2122
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++;
2128 }
2129 #endif
2130
2131 #ifdef CONFIG_TDLS
2132 if(ptdlsinfo->ch_sensing==1 && ptdlsinfo->cur_channel !=0){
2133 ptdlsinfo->collect_pkt_num[ptdlsinfo->cur_channel-1]++;
2134 }
2135 #endif //CONFIG_TDLS
2136
2137 #ifdef RTK_DMP_PLATFORM
2138 if ( 0 )
2139 {
2140 DBG_871X("++\n");
2141 {
2142 int i;
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));
2146
2147 }
2148 DBG_871X("--\n");
2149 }
2150 #endif //RTK_DMP_PLATFORM
2151
2152 //add version chk
2153 if(ver!=0){
2154 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_data_frame fail! (ver!=0)\n"));
2155 retval= _FAIL;
2156 goto exit;
2157 }
2158
2159 type = GetFrameType(ptr);
2160 subtype = GetFrameSubType(ptr); //bit(7)~bit(2)
2161
2162 pattrib->to_fr_ds = get_tofr_ds(ptr);
2163
2164 pattrib->frag_num = GetFragNum(ptr);
2165 pattrib->seq_num = GetSequence(ptr);
2166
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);
2172 #if 0 //for debug
2173
2174 if(pHalData->bDumpRxPkt ==1){
2175 int i;
2176 DBG_871X("############################# \n");
2177
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");
2182 }
2183 else if(pHalData->bDumpRxPkt ==2){
2184 if(type== WIFI_MGT_TYPE){
2185 int i;
2186 DBG_871X("############################# \n");
2187
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");
2192 }
2193 }
2194 else if(pHalData->bDumpRxPkt ==3){
2195 if(type== WIFI_DATA_TYPE){
2196 int i;
2197 DBG_871X("############################# \n");
2198
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");
2203 }
2204 }
2205
2206 #endif
2207 switch (type)
2208 {
2209 case WIFI_MGT_TYPE: //mgnt
2210 #ifdef CONFIG_IEEE80211W
2211 if(validate_80211w_mgmt(adapter, precv_frame) == _FAIL)
2212 {
2213 retval = _FAIL;
2214 break;
2215 }
2216 #endif //CONFIG_IEEE80211W
2217
2218 retval = validate_recv_mgnt_frame(adapter, precv_frame);
2219 if (retval == _FAIL)
2220 {
2221 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_mgnt_frame fail\n"));
2222 }
2223 retval = _FAIL; // only data frame return _SUCCESS
2224 break;
2225 case WIFI_CTRL_TYPE: //ctrl
2226 retval = validate_recv_ctrl_frame(adapter, precv_frame);
2227 if (retval == _FAIL)
2228 {
2229 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("validate_recv_ctrl_frame fail\n"));
2230 }
2231 retval = _FAIL; // only data frame return _SUCCESS
2232 break;
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)
2238 {
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++;
2242 }
2243 break;
2244 default:
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);
2248 #endif
2249 retval = _FAIL;
2250 break;
2251 }
2252
2253 exit:
2254
2255 _func_exit_;
2256
2257 return retval;
2258 }
2259
2260
2261 //remove the wlanhdr and add the eth_hdr
2262 #if 1
2263
2264 sint wlanhdr_to_ethhdr ( union recv_frame *precvframe);
2265 sint wlanhdr_to_ethhdr ( union recv_frame *precvframe)
2266 {
2267 sint rmv_len;
2268 u16 eth_type, len;
2269 u8 bsnaphdr;
2270 u8 *psnap_type;
2271 struct ieee80211_snap_hdr *psnap;
2272
2273 sint ret=_SUCCESS;
2274 _adapter *adapter =precvframe->u.hdr.adapter;
2275 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2276
2277 u8 *ptr = get_recvframe_data(precvframe) ; // point to frame_ctrl field
2278 struct rx_pkt_attrib *pattrib = & precvframe->u.hdr.attrib;
2279
2280 _func_enter_;
2281
2282 if(pattrib->encrypt){
2283 recvframe_pull_tail(precvframe, pattrib->icv_len);
2284 }
2285
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 */
2296 bsnaphdr = _TRUE;
2297 }
2298 else {
2299 /* Leave Ethernet header part of hdr and full payload */
2300 bsnaphdr = _FALSE;
2301 }
2302
2303 rmv_len = pattrib->hdrlen + pattrib->iv_len +(bsnaphdr?SNAP_SIZE:0);
2304 len = precvframe->u.hdr.len - rmv_len;
2305
2306 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("\n===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n\n", pattrib->hdrlen, pattrib->iv_len));
2307
2308 _rtw_memcpy(&eth_type, ptr+rmv_len, 2);
2309 eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type
2310 pattrib->eth_type = eth_type;
2311
2312 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE))
2313 {
2314 ptr += rmv_len ;
2315 *ptr = 0x87;
2316 *(ptr+1) = 0x12;
2317
2318 eth_type = 0x8712;
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);
2322 ptr+=24;
2323 }
2324 else {
2325 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+ (bsnaphdr?2:0)));
2326 }
2327
2328 _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2329 _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
2330
2331 if(!bsnaphdr) {
2332 len = htons(len);
2333 _rtw_memcpy(ptr+12, &len, 2);
2334 }
2335
2336 _func_exit_;
2337 return ret;
2338
2339 }
2340
2341 #else
2342
2343 sint wlanhdr_to_ethhdr ( union recv_frame *precvframe)
2344 {
2345 sint rmv_len;
2346 u16 eth_type;
2347 u8 bsnaphdr;
2348 u8 *psnap_type;
2349 struct ieee80211_snap_hdr *psnap;
2350
2351 sint ret=_SUCCESS;
2352 _adapter *adapter =precvframe->u.hdr.adapter;
2353 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
2354
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;
2358
2359 _func_enter_;
2360
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)
2364 {
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;
2372 else {
2373 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("drop pkt due to invalid frame format!\n"));
2374 ret= _FAIL;
2375 goto exit;
2376 }
2377
2378 } else
2379 bsnaphdr=_FALSE;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS;
2380
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));
2383
2384 if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE)
2385 {
2386 ptr += rmv_len ;
2387 *ptr = 0x87;
2388 *(ptr+1) = 0x12;
2389
2390 //back to original pointer
2391 ptr -= rmv_len;
2392 }
2393
2394 ptr += rmv_len ;
2395
2396 _rtw_memcpy(&eth_type, ptr, 2);
2397 eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type
2398 ptr +=2;
2399
2400 if(pattrib->encrypt){
2401 recvframe_pull_tail(precvframe, pattrib->icv_len);
2402 }
2403
2404 if(eth_type == 0x8100) //vlan
2405 {
2406 pvlan = (struct _vlan *) ptr;
2407
2408 //eth_type = get_vlan_encap_proto(pvlan);
2409 //eth_type = pvlan->h_vlan_encapsulated_proto;//?
2410 rmv_len += 4;
2411 ptr+=4;
2412 }
2413
2414 if(eth_type==0x0800)//ip
2415 {
2416 //struct iphdr* piphdr = (struct iphdr*) ptr;
2417 //__u8 tos = (unsigned char)(pattrib->priority & 0xff);
2418
2419 //piphdr->tos = tos;
2420
2421 //if (piphdr->protocol == 0x06)
2422 //{
2423 // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", precvframe->u.hdr.len));
2424 //}
2425 }
2426 else if(eth_type==0x8712)// append rx status for mp test packets
2427 {
2428 //ptr -= 16;
2429 //_rtw_memcpy(ptr, get_rxmem(precvframe), 16);
2430 }
2431 else
2432 {
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 );
2437
2438 VlanPriInfo.Value = // Get current value.
2439 NDIS_PER_PACKET_INFO_FROM_PACKET(precvframe->u.hdr.pkt, Ieee8021QInfo);
2440
2441 VlanPriInfo.TagHeader.UserPriority = UserPriority;
2442 VlanPriInfo.TagHeader.VlanId = VlanID ;
2443
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;
2447 #endif
2448 }
2449
2450 if(eth_type==0x8712)// append rx status for mp test packets
2451 {
2452 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24);
2453 _rtw_memcpy(ptr, get_rxmem(precvframe), 24);
2454 ptr+=24;
2455 }
2456 else
2457 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2));
2458
2459 _rtw_memcpy(ptr, pattrib->dst, ETH_ALEN);
2460 _rtw_memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN);
2461
2462 eth_type = htons((unsigned short)eth_type) ;
2463 _rtw_memcpy(ptr+12, &eth_type, 2);
2464
2465 exit:
2466
2467 _func_exit_;
2468
2469 return ret;
2470 }
2471 #endif
2472
2473
2474 #ifdef CONFIG_SDIO_HCI
2475 #ifdef PLATFORM_LINUX
2476 static void recvframe_expand_pkt(
2477 PADAPTER padapter,
2478 union recv_frame *prframe)
2479 {
2480 struct recv_frame_hdr *pfhdr;
2481 _pkt *ppkt;
2482 u8 shift_sz;
2483 u32 alloc_sz;
2484
2485
2486 pfhdr = &prframe->u.hdr;
2487
2488 // 6 is for IP header 8 bytes alignment in QoS packet case.
2489 if (pfhdr->attrib.qos)
2490 shift_sz = 6;
2491 else
2492 shift_sz = 0;
2493
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
2499
2500 //3 1. alloc new skb
2501 // prepare extra space for 4 bytes alignment
2502 ppkt = rtw_skb_alloc(alloc_sz);
2503
2504 if (!ppkt) return; // no way to expand
2505
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);
2511
2512 // copy data to new pkt
2513 _rtw_memcpy(skb_put(ppkt, pfhdr->len), pfhdr->rx_data, pfhdr->len);
2514
2515 rtw_skb_free(pfhdr->pkt);
2516
2517 // attach new pkt to recvframe
2518 pfhdr->pkt = ppkt;
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);
2523 }
2524 #else
2525 #warning "recvframe_expand_pkt not implement, defrag may crash system"
2526 #endif
2527 #endif
2528
2529 //perform defrag
2530 union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q);
2531 union recv_frame * recvframe_defrag(_adapter *adapter,_queue *defrag_q)
2532 {
2533 _list *plist, *phead;
2534 u8 *data,wlanhdr_offset;
2535 u8 curfragnum;
2536 struct recv_frame_hdr *pfhdr,*pnfhdr;
2537 union recv_frame* prframe, *pnextrframe;
2538 _queue *pfree_recv_queue;
2539
2540 _func_enter_;
2541
2542 curfragnum=0;
2543 pfree_recv_queue=&adapter->recvpriv.free_recv_queue;
2544
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));
2550
2551 if(curfragnum!=pfhdr->attrib.frag_num)
2552 {
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);
2557
2558 return NULL;
2559 }
2560
2561 #ifdef CONFIG_SDIO_HCI
2562 recvframe_expand_pkt(adapter, prframe);
2563 #endif
2564
2565 curfragnum++;
2566
2567 plist= get_list_head(defrag_q);
2568
2569 plist = get_next(plist);
2570
2571 data=get_recvframe_data(prframe);
2572
2573 while(rtw_end_of_queue_search(phead, plist) == _FALSE)
2574 {
2575 pnextrframe = LIST_CONTAINOR(plist, union recv_frame , u);
2576 pnfhdr=&pnextrframe->u.hdr;
2577
2578
2579 //check the fragment sequence (2nd ~n fragment frame)
2580
2581 if(curfragnum!=pnfhdr->attrib.frag_num)
2582 {
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);
2587 return NULL;
2588 }
2589
2590 curfragnum++;
2591
2592 //copy the 2nd~n fragment frame's payload to the first fragment
2593 //get the 2nd~last fragment frame's payload
2594
2595 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
2596
2597 recvframe_pull(pnextrframe, wlanhdr_offset);
2598
2599 //append to first fragment frame's tail (if privacy frame, pull the ICV)
2600 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
2601
2602 //memcpy
2603 _rtw_memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
2604
2605 recvframe_put(prframe, pnfhdr->len);
2606
2607 pfhdr->attrib.icv_len=pnfhdr->attrib.icv_len;
2608 plist = get_next(plist);
2609
2610 };
2611
2612 //free the defrag_q queue and return the prframe
2613 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
2614
2615 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Performance defrag!!!!!\n"));
2616
2617 _func_exit_;
2618
2619 return prframe;
2620 }
2621
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)
2624 {
2625 u8 ismfrag;
2626 u8 fragnum;
2627 u8 *psta_addr;
2628 struct recv_frame_hdr *pfhdr;
2629 struct sta_info *psta;
2630 struct sta_priv *pstapriv;
2631 _list *phead;
2632 union recv_frame *prtnframe = NULL;
2633 _queue *pfree_recv_queue, *pdefrag_q;
2634
2635 _func_enter_;
2636
2637 pstapriv = &padapter->stapriv;
2638
2639 pfhdr = &precv_frame->u.hdr;
2640
2641 pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
2642
2643 //need to define struct of wlan header frame ctrl
2644 ismfrag = pfhdr->attrib.mfrag;
2645 fragnum = pfhdr->attrib.frag_num;
2646
2647 psta_addr = pfhdr->attrib.ta;
2648 psta = rtw_get_stainfo(pstapriv, psta_addr);
2649 if (psta == NULL)
2650 {
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;
2655 } else
2656 pdefrag_q = NULL;
2657 }
2658 else
2659 pdefrag_q = &psta->sta_recvpriv.defrag_q;
2660
2661 if ((ismfrag==0) && (fragnum==0))
2662 {
2663 prtnframe = precv_frame;//isn't a fragment frame
2664 }
2665
2666 if (ismfrag==1)
2667 {
2668 //0~(n-1) fragment frame
2669 //enqueue to defraf_g
2670 if(pdefrag_q != NULL)
2671 {
2672 if(fragnum==0)
2673 {
2674 //the first fragment
2675 if(_rtw_queue_empty(pdefrag_q) == _FALSE)
2676 {
2677 //free current defrag_q
2678 rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
2679 }
2680 }
2681
2682
2683 //Then enqueue the 0~(n-1) fragment into the defrag_q
2684
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);
2689
2690 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("Enqueuq: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum));
2691
2692 prtnframe=NULL;
2693
2694 }
2695 else
2696 {
2697 //can't find this ta's defrag_queue, so free this recv_frame
2698 rtw_free_recvframe(precv_frame, pfree_recv_queue);
2699 prtnframe=NULL;
2700 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag, fragnum));
2701 }
2702
2703 }
2704
2705 if((ismfrag==0)&&(fragnum!=0))
2706 {
2707 //the last fragment frame
2708 //enqueue the last fragment
2709 if(pdefrag_q != NULL)
2710 {
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);
2715
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;
2720
2721 }
2722 else
2723 {
2724 //can't find this ta's defrag_queue, so free this recv_frame
2725 rtw_free_recvframe(precv_frame, pfree_recv_queue);
2726 prtnframe=NULL;
2727 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("Free because pdefrag_q ==NULL: ismfrag = %d, fragnum= %d\n", ismfrag,fragnum));
2728 }
2729
2730 }
2731
2732
2733 if((prtnframe!=NULL)&&(prtnframe->u.hdr.attrib.privacy))
2734 {
2735 //after defrag we must check tkip mic code
2736 if(recvframe_chkmic(padapter, prtnframe)==_FAIL)
2737 {
2738 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvframe_chkmic(padapter, prtnframe)==_FAIL\n"));
2739 rtw_free_recvframe(prtnframe,pfree_recv_queue);
2740 prtnframe=NULL;
2741 }
2742 }
2743
2744 _func_exit_;
2745
2746 return prtnframe;
2747
2748 }
2749
2750 #define ENDIAN_FREE 1
2751
2752 int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe);
2753 int amsdu_to_msdu(_adapter *padapter, union recv_frame *prframe)
2754 {
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;
2758 u8 nr_subframes, i;
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);
2767 int ret = _SUCCESS;
2768 #ifdef PLATFORM_FREEBSD
2769 struct mbuf *sub_m=NULL, *subframes[MAX_SUBFRAME_COUNT];
2770 u8 *ptr,offset;
2771 #endif //PLATFORM_FREEBSD
2772 nr_subframes = 0;
2773
2774 pattrib = &prframe->u.hdr.attrib;
2775
2776 recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
2777
2778 if(prframe->u.hdr.attrib.iv_len >0)
2779 {
2780 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
2781 }
2782
2783 a_len = prframe->u.hdr.len;
2784
2785 pdata = prframe->u.hdr.rx_data;
2786
2787 while(a_len > ETH_HLEN) {
2788
2789 /* Offset 12 denote 2 mac address */
2790 #ifdef ENDIAN_FREE
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
2799
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);
2802 goto exit;
2803 }
2804
2805 #ifndef PLATFORM_FREEBSD
2806 /* move the data point to data content */
2807 pdata += ETH_HLEN;
2808 a_len -= ETH_HLEN;
2809
2810 /* Allocate new skb for releasing to upper layer */
2811 #ifdef CONFIG_SKB_COPY
2812 sub_skb = rtw_skb_alloc(nSubframe_Length + 12);
2813 if(sub_skb)
2814 {
2815 skb_reserve(sub_skb, 12);
2816 data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
2817 _rtw_memcpy(data_ptr, pdata, nSubframe_Length);
2818 }
2819 else
2820 #endif // CONFIG_SKB_COPY
2821 {
2822 sub_skb = rtw_skb_clone(prframe->u.hdr.pkt);
2823 if(sub_skb)
2824 {
2825 sub_skb->data = pdata;
2826 sub_skb->len = nSubframe_Length;
2827 skb_set_tail_pointer(sub_skb, nSubframe_Length);
2828 }
2829 else
2830 {
2831 DBG_871X("rtw_skb_clone() Fail!!! , nr_subframes = %d\n",nr_subframes);
2832 break;
2833 }
2834 }
2835
2836 #else // PLATFORM_FREEBSD
2837
2838 //PLATFORM_FREEBSD
2839 //Allocate a mbuff,
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);
2842
2843 pdata += ETH_HLEN;
2844 a_len -= ETH_HLEN;
2845 #endif // PLATFORM_FREEBSD
2846
2847 #ifndef PLATFORM_FREEBSD
2848 //sub_skb->dev = padapter->pnetdev;
2849 subframes[nr_subframes++] = sub_skb;
2850 #else //PLATFORM_FREEBSD
2851 //PLATFORM_FREEBSD
2852 subframes[nr_subframes++] = sub_m;
2853 #endif //PLATFORM_FREEBSD
2854
2855 if(nr_subframes >= MAX_SUBFRAME_COUNT) {
2856 DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n");
2857 break;
2858 }
2859
2860 pdata += nSubframe_Length;
2861 a_len -= nSubframe_Length;
2862 if(a_len != 0) {
2863 padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1));
2864 if(padding_len == 4) {
2865 padding_len = 0;
2866 }
2867
2868 if(a_len < padding_len) {
2869 goto exit;
2870 }
2871 pdata += padding_len;
2872 a_len -= padding_len;
2873 }
2874 }
2875
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 */
2880 #ifdef ENDIAN_FREE
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);
2894 } else {
2895 u16 len;
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);
2901 }
2902
2903 /* Indicat the packets to upper layer */
2904 if (sub_skb) {
2905 //memset(sub_skb->cb, 0, sizeof(sub_skb->cb));
2906
2907 #ifdef CONFIG_BR_EXT
2908 // Insert NAT2.5 RX here!
2909 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2910 void *br_port = NULL;
2911
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))
2915 rcu_read_lock();
2916 br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
2917 rcu_read_unlock();
2918 #endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
2919
2920
2921 if( br_port && (check_fwstate(pmlmepriv, WIFI_STATION_STATE|WIFI_ADHOC_STATE) == _TRUE) )
2922 {
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");
2927 //return FAIL;
2928
2929 #if 1
2930 // bypass this frame to upper layer!!
2931 #else
2932 rtw_skb_free(sub_skb);
2933 continue;
2934 #endif
2935 }
2936 }
2937 #endif // CONFIG_BR_EXT
2938
2939 sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
2940 sub_skb->dev = padapter->pnetdev;
2941
2942 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
2943 if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) {
2944 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
2945 } else {
2946 sub_skb->ip_summed = CHECKSUM_NONE;
2947 }
2948 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
2949 sub_skb->ip_summed = CHECKSUM_NONE;
2950 #endif //CONFIG_TCP_CSUM_OFFLOAD_RX
2951
2952 rtw_netif_rx(padapter->pnetdev, sub_skb);
2953 }
2954 #else //PLATFORM_FREEBSD
2955
2956 //PLATFORM_FREEBSD
2957 sub_m = subframes[i];
2958 ptr=mtod(sub_m, u8 *);
2959 offset=ETH_HLEN;
2960 /* convert hdr + possible LLC headers into Ethernet header */
2961 #ifdef ENDIAN_FREE
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 */
2971 offset+=SNAP_SIZE;
2972 _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->src, ETH_ALEN);
2973 offset-=ETH_ALEN;
2974 _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->dst, ETH_ALEN);
2975 offset-=ETH_ALEN;
2976 } else {
2977 u16 len;
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);
2981 offset-=2;
2982 _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->src, ETH_ALEN);
2983 offset-=ETH_ALEN;
2984 _rtw_memcpy(&ptr[offset-ETH_ALEN], pattrib->dst, ETH_ALEN);
2985 offset-=ETH_ALEN;
2986 }
2987
2988 m_adj(sub_m,offset);
2989
2990 /* Indicat the packets to upper layer */
2991 if (sub_m) {
2992
2993 #if 0
2994 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
2995 if ( (pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1) ) {
2996 sub_skb->ip_summed = CHECKSUM_UNNECESSARY;
2997 } else {
2998 sub_skb->ip_summed = CHECKSUM_NONE;
2999 }
3000 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
3001 sub_skb->ip_summed = CHECKSUM_NONE;
3002 #endif //CONFIG_TCP_CSUM_OFFLOAD_RX
3003 #endif //0
3004
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);
3011 }
3012 #else // CONFIG_RX_INDICATE_QUEUE
3013 (*padapter->pifp->if_input)(padapter->pifp, sub_m);
3014 #endif // CONFIG_RX_INDICATE_QUEUE
3015 }
3016
3017 #endif //PLATFORM_FREEBSD
3018 }
3019
3020 exit:
3021
3022 prframe->u.hdr.len=0;
3023 rtw_free_recvframe(prframe, pfree_recv_queue);//free this recv_frame
3024
3025 return ret;
3026 #else // || defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
3027 #ifdef PLATFORM_WINDOWS
3028 _irqL irql;
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;
3034 u8 bsnaphdr;
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);
3039 int ret = _SUCCESS;
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;
3044
3045 recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen);
3046
3047 if(prframe->u.hdr.attrib.iv_len >0)
3048 {
3049 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len);
3050 }
3051
3052 pdata = prframe->u.hdr.rx_data;
3053
3054 prframe->u.hdr.len=0;
3055
3056 pnrframe = prframe;
3057
3058
3059 do{
3060
3061 mv_len=0;
3062 pnrframe->u.hdr.rx_data = pnrframe->u.hdr.rx_tail = pdata;
3063 ptr = pdata;
3064
3065
3066 _rtw_memcpy(pnrframe->u.hdr.attrib.dst, ptr, ETH_ALEN);
3067 ptr+=ETH_ALEN;
3068 _rtw_memcpy(pnrframe->u.hdr.attrib.src, ptr, ETH_ALEN);
3069 ptr+=ETH_ALEN;
3070
3071 _rtw_memcpy(&type_len, ptr, 2);
3072 type_len= ntohs((unsigned short )type_len);
3073 ptr +=2;
3074 mv_len += ETH_HLEN;
3075
3076 recvframe_put(pnrframe, type_len+ETH_HLEN);//update tail;
3077
3078 if(pnrframe->u.hdr.rx_data >= pnrframe->u.hdr.rx_tail || type_len<8)
3079 {
3080 //panic("pnrframe->u.hdr.rx_data >= pnrframe->u.hdr.rx_tail || type_len<8\n");
3081
3082 rtw_free_recvframe(pnrframe, pfree_recv_queue);
3083
3084 goto exit;
3085 }
3086
3087 psnap=(struct ieee80211_snap_hdr *)(ptr);
3088 psnap_type=ptr+SNAP_SIZE;
3089 if (psnap->dsap==0xaa && psnap->ssap==0xaa && psnap->ctrl==0x03)
3090 {
3091 if ( _rtw_memcmp(psnap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN))
3092 {
3093 bsnaphdr=_TRUE;//wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_RFC1042;
3094 }
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) )
3097 {
3098 bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_APPLETALK;
3099 }
3100 else if (_rtw_memcmp( psnap->oui, oui_8021h, WLAN_IEEE_OUI_LEN))
3101 {
3102 bsnaphdr=_TRUE; //wlan_pkt_format = WLAN_PKT_FORMAT_SNAP_TUNNEL;
3103 }
3104 else
3105 {
3106 RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("drop pkt due to invalid frame format!\n"));
3107
3108 //KeBugCheckEx(0x87123333, 0xe0, 0x4c, 0x87, 0xdd);
3109
3110 //panic("0x87123333, 0xe0, 0x4c, 0x87, 0xdd\n");
3111
3112 rtw_free_recvframe(pnrframe, pfree_recv_queue);
3113
3114 goto exit;
3115 }
3116
3117 }
3118 else
3119 {
3120 bsnaphdr=_FALSE;//wlan_pkt_format = WLAN_PKT_FORMAT_OTHERS;
3121 }
3122
3123 ptr += (bsnaphdr?SNAP_SIZE:0);
3124 _rtw_memcpy(&eth_type, ptr, 2);
3125 eth_type= ntohs((unsigned short )eth_type); //pattrib->ether_type
3126
3127 mv_len+= 2+(bsnaphdr?SNAP_SIZE:0);
3128 ptr += 2;//now move to iphdr;
3129
3130 pvlan = NULL;
3131 if(eth_type == 0x8100) //vlan
3132 {
3133 pvlan = (struct _vlan *)ptr;
3134 ptr+=4;
3135 mv_len+=4;
3136 }
3137
3138 if(eth_type==0x0800)//ip
3139 {
3140 struct iphdr* piphdr = (struct iphdr*)ptr;
3141
3142
3143 if (piphdr->protocol == 0x06)
3144 {
3145 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("@@@===recv tcp len:%d @@@===\n", pnrframe->u.hdr.len));
3146 }
3147 }
3148 #ifdef PLATFORM_OS_XP
3149 else
3150 {
3151 NDIS_PACKET_8021Q_INFO VlanPriInfo;
3152 UINT32 UserPriority = pnrframe->u.hdr.attrib.priority;
3153 UINT32 VlanID = (pvlan!=NULL ? get_vlan_id(pvlan) : 0 );
3154
3155 VlanPriInfo.Value = // Get current value.
3156 NDIS_PER_PACKET_INFO_FROM_PACKET(pnrframe->u.hdr.pkt, Ieee8021QInfo);
3157
3158 VlanPriInfo.TagHeader.UserPriority = UserPriority;
3159 VlanPriInfo.TagHeader.VlanId = VlanID;
3160
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;
3164
3165 }
3166 #endif //PLATFORM_OS_XP
3167
3168 pbuf = recvframe_pull(pnrframe, (mv_len-sizeof(struct ethhdr)));
3169
3170 _rtw_memcpy(pbuf, pnrframe->u.hdr.attrib.dst, ETH_ALEN);
3171 _rtw_memcpy(pbuf+ETH_ALEN, pnrframe->u.hdr.attrib.src, ETH_ALEN);
3172
3173 eth_type = htons((unsigned short)eth_type) ;
3174 _rtw_memcpy(pbuf+12, &eth_type, 2);
3175
3176 padding_len = (4) - ((type_len + ETH_HLEN)&(4-1));
3177
3178 a_len -= (type_len + ETH_HLEN + padding_len) ;
3179
3180
3181 #if 0
3182
3183 if(a_len > ETH_HLEN)
3184 {
3185 pnrframe_new = rtw_alloc_recvframe(pfree_recv_queue);
3186 if(pnrframe_new)
3187 {
3188 _pkt *pskb_copy;
3189 unsigned int copy_len = pnrframe->u.hdr.len;
3190
3191 _rtw_init_listhead(&pnrframe_new->u.hdr.list);
3192
3193 pskb_copy = rtw_skb_alloc(copy_len+64);
3194
3195 if(pskb_copy==NULL)
3196 {
3197 DBG_871X("amsdu_to_msdu:can not all(ocate memory for skb copy\n");
3198 }
3199
3200 pnrframe_new->u.hdr.pkt = pskb_copy;
3201
3202 _rtw_memcpy(pskb_copy->data, pnrframe->u.hdr.rx_data, copy_len);
3203
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;
3206
3207
3208 if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE))
3209 {
3210 rtw_recv_indicatepkt(padapter, pnrframe_new);//indicate this recv_frame
3211 }
3212 else
3213 {
3214 rtw_free_recvframe(pnrframe_new, pfree_recv_queue);//free this recv_frame
3215 }
3216
3217 }
3218 else
3219 {
3220 DBG_871X("amsdu_to_msdu:can not allocate memory for pnrframe_new\n");
3221 }
3222
3223 }
3224 else
3225 {
3226 if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE))
3227 {
3228 rtw_recv_indicatepkt(padapter, pnrframe);//indicate this recv_frame
3229 }
3230 else
3231 {
3232 rtw_free_recvframe(pnrframe, pfree_recv_queue);//free this recv_frame
3233 }
3234
3235 pnrframe = NULL;
3236
3237 }
3238
3239 #else // 0
3240
3241 //padding_len = (4) - ((type_len + ETH_HLEN)&(4-1));
3242
3243 //a_len -= (type_len + ETH_HLEN + padding_len) ;
3244
3245 pnrframe_new = NULL;
3246
3247
3248 if(a_len > ETH_HLEN)
3249 {
3250 pnrframe_new = rtw_alloc_recvframe(pfree_recv_queue);
3251
3252 if(pnrframe_new)
3253 {
3254
3255
3256 //pnrframe_new->u.hdr.precvbuf = precvbuf;//precvbuf is assigned before call rtw_init_recvframe()
3257 //rtw_init_recvframe(pnrframe_new, precvpriv);
3258 {
3259 #ifdef PLATFORM_LINUX
3260 _pkt *pskb = pnrframe->u.hdr.pkt;
3261 #endif //PLATFORM_LINUX
3262 _rtw_init_listhead(&pnrframe_new->u.hdr.list);
3263
3264 pnrframe_new->u.hdr.len=0;
3265
3266 #ifdef PLATFORM_LINUX
3267 if(pskb)
3268 {
3269 pnrframe_new->u.hdr.pkt = rtw_skb_clone(pskb);
3270 }
3271 #endif //PLATFORM_LINUX
3272
3273 }
3274
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;//
3278
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
3285
3286 }
3287 else
3288 {
3289 //panic("pnrframe_new=%x\n", pnrframe_new);
3290 }
3291 }
3292
3293
3294 if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE) )
3295 {
3296 rtw_recv_indicatepkt(padapter, pnrframe);//indicate this recv_frame
3297 }
3298 else
3299 {
3300 rtw_free_recvframe(pnrframe, pfree_recv_queue);//free this recv_frame
3301 }
3302
3303
3304 pnrframe = NULL;
3305 if(pnrframe_new)
3306 {
3307 pnrframe = pnrframe_new;
3308 }
3309
3310
3311 #endif // end defined (PLATFORM_LINUX) || defined (PLATFORM_FREEBSD)
3312
3313 }while(pnrframe);
3314
3315 exit:
3316
3317 return ret;
3318 #endif
3319 }
3320
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)
3323 {
3324 u8 wsize = preorder_ctrl->wsize_b;
3325 u16 wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;//% 4096;
3326
3327 // Rx Reorder initialize condition.
3328 if (preorder_ctrl->indicate_seq == 0xFFFF)
3329 {
3330 preorder_ctrl->indicate_seq = seq_num;
3331 #ifdef DBG_RX_SEQ
3332 DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3333 preorder_ctrl->indicate_seq, seq_num);
3334 #endif
3335
3336 //DbgPrint("check_indicate_seq, 1st->indicate_seq=%d\n", precvpriv->indicate_seq);
3337 }
3338
3339 //DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num);
3340
3341 // Drop out the packet which SeqNum is smaller than WinStart
3342 if( SN_LESS(seq_num, preorder_ctrl->indicate_seq) )
3343 {
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);
3346
3347 #ifdef DBG_RX_DROP_FRAME
3348 DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __FUNCTION__,
3349 preorder_ctrl->indicate_seq, seq_num);
3350 #endif
3351
3352
3353 return _FALSE;
3354 }
3355
3356 //
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
3360 //
3361 if( SN_EQUAL(seq_num, preorder_ctrl->indicate_seq) )
3362 {
3363 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3364 #ifdef DBG_RX_SEQ
3365 DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3366 preorder_ctrl->indicate_seq, seq_num);
3367 #endif
3368 }
3369 else if(SN_LESS(wend, seq_num))
3370 {
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);
3373
3374 // boundary situation, when seq_num cross 0xFFF
3375 if(seq_num >= (wsize - 1))
3376 preorder_ctrl->indicate_seq = seq_num + 1 -wsize;
3377 else
3378 preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
3379
3380 #ifdef DBG_RX_SEQ
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);
3383 #endif
3384 }
3385
3386 //DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num);
3387
3388 return _TRUE;
3389 }
3390
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)
3393 {
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;
3399
3400 //DbgPrint("+enqueue_reorder_recvframe()\n");
3401
3402 //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql);
3403 //_rtw_spinlock_ex(&ppending_recvframe_queue->lock);
3404
3405
3406 phead = get_list_head(ppending_recvframe_queue);
3407 plist = get_next(phead);
3408
3409 while(rtw_end_of_queue_search(phead, plist) == _FALSE)
3410 {
3411 pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u);
3412 pnextattrib = &pnextrframe->u.hdr.attrib;
3413
3414 if(SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
3415 {
3416 plist = get_next(plist);
3417 }
3418 else if( SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
3419 {
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));
3422
3423 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3424
3425 return _FALSE;
3426 }
3427 else
3428 {
3429 break;
3430 }
3431
3432 //DbgPrint("enqueue_reorder_recvframe():while\n");
3433
3434 }
3435
3436
3437 //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql);
3438 //_rtw_spinlock_ex(&ppending_recvframe_queue->lock);
3439
3440 rtw_list_delete(&(prframe->u.hdr.list));
3441
3442 rtw_list_insert_tail(&(prframe->u.hdr.list), plist);
3443
3444 //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock);
3445 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3446
3447
3448 //RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum));
3449 return _TRUE;
3450
3451 }
3452
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)
3455 {
3456 //_irqL irql;
3457 //u8 bcancelled;
3458 _list *phead, *plist;
3459 union recv_frame *prframe;
3460 struct rx_pkt_attrib *pattrib;
3461 //u8 index = 0;
3462 int bPktInBuf = _FALSE;
3463 struct recv_priv *precvpriv = &padapter->recvpriv;
3464 _queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
3465
3466 //DbgPrint("+recv_indicatepkts_in_order\n");
3467
3468 //_enter_critical_ex(&ppending_recvframe_queue->lock, &irql);
3469 //_rtw_spinlock_ex(&ppending_recvframe_queue->lock);
3470
3471 phead = get_list_head(ppending_recvframe_queue);
3472 plist = get_next(phead);
3473
3474 #if 0
3475 // Check if there is any other indication thread running.
3476 if(pTS->RxIndicateState == RXTS_INDICATE_PROCESSING)
3477 return;
3478 #endif
3479
3480 // Handling some condition for forced indicate case.
3481 if(bforced==_TRUE)
3482 {
3483 if(rtw_is_list_empty(phead))
3484 {
3485 // _exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3486 //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock);
3487 return _TRUE;
3488 }
3489
3490 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3491 pattrib = &prframe->u.hdr.attrib;
3492 preorder_ctrl->indicate_seq = pattrib->seq_num;
3493 #ifdef DBG_RX_SEQ
3494 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3495 preorder_ctrl->indicate_seq, pattrib->seq_num);
3496 #endif
3497 }
3498
3499 // Prepare indication list and indication.
3500 // Check if there is any packet need indicate.
3501 while(!rtw_is_list_empty(phead))
3502 {
3503
3504 prframe = LIST_CONTAINOR(plist, union recv_frame, u);
3505 pattrib = &prframe->u.hdr.attrib;
3506
3507 if(!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num))
3508 {
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));
3512
3513 #if 0
3514 // This protect buffer from overflow.
3515 if(index >= REORDER_WIN_SIZE)
3516 {
3517 RT_ASSERT(FALSE, ("IndicateRxReorderList(): Buffer overflow!! \n"));
3518 bPktInBuf = TRUE;
3519 break;
3520 }
3521 #endif
3522
3523 plist = get_next(plist);
3524 rtw_list_delete(&(prframe->u.hdr.list));
3525
3526 if(SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num))
3527 {
3528 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
3529 #ifdef DBG_RX_SEQ
3530 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3531 preorder_ctrl->indicate_seq, pattrib->seq_num);
3532 #endif
3533 }
3534
3535 #if 0
3536 index++;
3537 if(index==1)
3538 {
3539 //Cancel previous pending timer.
3540 //PlatformCancelTimer(Adapter, &pTS->RxPktPendingTimer);
3541 if(bforced!=_TRUE)
3542 {
3543 //DBG_871X("_cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);\n");
3544 _cancel_timer(&preorder_ctrl->reordering_ctrl_timer, &bcancelled);
3545 }
3546 }
3547 #endif
3548
3549 //Set this as a lock to make sure that only one thread is indicating packet.
3550 //pTS->RxIndicateState = RXTS_INDICATE_PROCESSING;
3551
3552 // Indicate packets
3553 //RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!! \n"));
3554
3555
3556 //indicate this recv_frame
3557 //DbgPrint("recv_indicatepkts_in_order, indicate_seq=%d, seq_num=%d\n", precvpriv->indicate_seq, pattrib->seq_num);
3558 if(!pattrib->amsdu)
3559 {
3560 //DBG_871X("recv_indicatepkts_in_order, amsdu!=1, indicate_seq=%d, seq_num=%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num);
3561
3562 if ((padapter->bDriverStopped == _FALSE) &&
3563 (padapter->bSurpriseRemoved == _FALSE))
3564 {
3565
3566 rtw_recv_indicatepkt(padapter, prframe);//indicate this recv_frame
3567
3568 }
3569 }
3570 else if(pattrib->amsdu==1)
3571 {
3572 if(amsdu_to_msdu(padapter, prframe)!=_SUCCESS)
3573 {
3574 rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
3575 }
3576 }
3577 else
3578 {
3579 //error condition;
3580 }
3581
3582
3583 //Update local variables.
3584 bPktInBuf = _FALSE;
3585
3586 }
3587 else
3588 {
3589 bPktInBuf = _TRUE;
3590 break;
3591 }
3592
3593 //DbgPrint("recv_indicatepkts_in_order():while\n");
3594
3595 }
3596
3597 //_rtw_spinunlock_ex(&ppending_recvframe_queue->lock);
3598 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3599
3600 /*
3601 //Release the indication lock and set to new indication step.
3602 if(bPktInBuf)
3603 {
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);
3609 }
3610 else
3611 {
3612 //pTS->RxIndicateState = RXTS_INDICATE_IDLE;
3613 }
3614 */
3615 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3616
3617 //return _TRUE;
3618 return bPktInBuf;
3619
3620 }
3621
3622 int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe);
3623 int recv_indicatepkt_reorder(_adapter *padapter, union recv_frame *prframe)
3624 {
3625 _irqL irql;
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;
3630
3631 if(!pattrib->amsdu)
3632 {
3633 //s1.
3634 wlanhdr_to_ethhdr(prframe);
3635
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)
3639 {
3640 if ((padapter->bDriverStopped == _FALSE) &&
3641 (padapter->bSurpriseRemoved == _FALSE))
3642 {
3643 RT_TRACE(_module_rtl871x_recv_c_, _drv_alert_, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n" ));
3644
3645 rtw_recv_indicatepkt(padapter, prframe);
3646 return _SUCCESS;
3647
3648 }
3649
3650 #ifdef DBG_RX_DROP_FRAME
3651 DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos !=1\n", __FUNCTION__);
3652 #endif
3653
3654 return _FAIL;
3655
3656 }
3657
3658 if (preorder_ctrl->enable == _FALSE)
3659 {
3660 //indicate this recv_frame
3661 preorder_ctrl->indicate_seq = pattrib->seq_num;
3662 #ifdef DBG_RX_SEQ
3663 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3664 preorder_ctrl->indicate_seq, pattrib->seq_num);
3665 #endif
3666
3667 rtw_recv_indicatepkt(padapter, prframe);
3668
3669 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
3670 #ifdef DBG_RX_SEQ
3671 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3672 preorder_ctrl->indicate_seq, pattrib->seq_num);
3673 #endif
3674
3675 return _SUCCESS;
3676 }
3677
3678 #ifndef CONFIG_RECV_REORDERING_CTRL
3679 //indicate this recv_frame
3680 rtw_recv_indicatepkt(padapter, prframe);
3681 return _SUCCESS;
3682 #endif
3683
3684 }
3685 else if(pattrib->amsdu==1) //temp filter -> means didn't support A-MSDUs in a A-MPDU
3686 {
3687 if (preorder_ctrl->enable == _FALSE)
3688 {
3689 preorder_ctrl->indicate_seq = pattrib->seq_num;
3690 #ifdef DBG_RX_SEQ
3691 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3692 preorder_ctrl->indicate_seq, pattrib->seq_num);
3693 #endif
3694
3695 retval = amsdu_to_msdu(padapter, prframe);
3696
3697 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096;
3698 #ifdef DBG_RX_SEQ
3699 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __FUNCTION__, __LINE__,
3700 preorder_ctrl->indicate_seq, pattrib->seq_num);
3701 #endif
3702
3703 if(retval != _SUCCESS){
3704 #ifdef DBG_RX_DROP_FRAME
3705 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__);
3706 #endif
3707 }
3708
3709 return retval;
3710 }
3711 }
3712 else
3713 {
3714
3715 }
3716
3717 _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3718
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));
3722
3723 //s2. check if winstart_b(indicate_seq) needs to been updated
3724 if(!check_indicate_seq(preorder_ctrl, pattrib->seq_num))
3725 {
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);
3730 //return _FAIL;
3731
3732 #ifdef DBG_RX_DROP_FRAME
3733 DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __FUNCTION__);
3734 #endif
3735 #if 0
3736 rtw_recv_indicatepkt(padapter, prframe);
3737
3738 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3739
3740 goto _success_exit;
3741 #else
3742 goto _err_exit;
3743 #endif
3744 }
3745
3746
3747 //s3. Insert all packet into Reorder Queue to maintain its ordering.
3748 if(!enqueue_reorder_recvframe(preorder_ctrl, prframe))
3749 {
3750 //DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n");
3751 //_exit_critical_ex(&ppending_recvframe_queue->lock, &irql);
3752 //return _FAIL;
3753 #ifdef DBG_RX_DROP_FRAME
3754 DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __FUNCTION__);
3755 #endif
3756 goto _err_exit;
3757 }
3758
3759
3760 //s4.
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.
3764 //
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.
3768 //
3769
3770 //recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE);
3771 if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _FALSE)==_TRUE)
3772 {
3773 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3774 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3775 }
3776 else
3777 {
3778 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3779 _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
3780 }
3781
3782
3783 _success_exit:
3784
3785 return _SUCCESS;
3786
3787 _err_exit:
3788
3789 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3790
3791 return _FAIL;
3792 }
3793
3794
3795 void rtw_reordering_ctrl_timeout_handler(void *pcontext)
3796 {
3797 _irqL irql;
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;
3801
3802
3803 if(padapter->bDriverStopped ||padapter->bSurpriseRemoved)
3804 {
3805 return;
3806 }
3807
3808 //DBG_871X("+rtw_reordering_ctrl_timeout_handler()=>\n");
3809
3810 _enter_critical_bh(&ppending_recvframe_queue->lock, &irql);
3811
3812 if(recv_indicatepkts_in_order(padapter, preorder_ctrl, _TRUE)==_TRUE)
3813 {
3814 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
3815 }
3816
3817 _exit_critical_bh(&ppending_recvframe_queue->lock, &irql);
3818
3819 }
3820
3821 int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe);
3822 int process_recv_indicatepkts(_adapter *padapter, union recv_frame *prframe)
3823 {
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;
3828 #ifdef CONFIG_TDLS
3829 struct sta_info *psta = prframe->u.hdr.psta;
3830 #endif //CONFIG_TDLS
3831
3832 #ifdef CONFIG_80211N_HT
3833
3834 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
3835
3836 #ifdef CONFIG_TDLS
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
3841 #else
3842 if(phtpriv->ht_option==_TRUE) //B/G/N Mode
3843 #endif //CONFIG_TDLS
3844 {
3845 //prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority];
3846
3847 if(recv_indicatepkt_reorder(padapter, prframe)!=_SUCCESS)// including perform A-MPDU Rx Ordering Buffer Control
3848 {
3849 #ifdef DBG_RX_DROP_FRAME
3850 DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __FUNCTION__);
3851 #endif
3852
3853 if ((padapter->bDriverStopped == _FALSE) &&
3854 (padapter->bSurpriseRemoved == _FALSE))
3855 {
3856 retval = _FAIL;
3857 return retval;
3858 }
3859 }
3860 }
3861 else //B/G mode
3862 #endif
3863 {
3864 retval=wlanhdr_to_ethhdr (prframe);
3865 if(retval != _SUCCESS)
3866 {
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__);
3870 #endif
3871 return retval;
3872 }
3873
3874 if ((padapter->bDriverStopped ==_FALSE)&&( padapter->bSurpriseRemoved==_FALSE))
3875 {
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);
3879
3880
3881 }
3882 else
3883 {
3884 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n" ));
3885
3886 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved));
3887 retval = _FAIL;
3888 return retval;
3889 }
3890
3891 }
3892
3893 return retval;
3894
3895 }
3896
3897 static int recv_func_prehandle(_adapter *padapter, union recv_frame *rframe)
3898 {
3899 int ret = _SUCCESS;
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;
3903
3904 #ifdef CONFIG_MP_INCLUDED
3905 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3906 #endif //CONFIG_MP_INCLUDED
3907
3908 #ifdef CONFIG_MP_INCLUDED
3909 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == _TRUE))//&&(padapter->mppriv.check_mp_pkt == 0))
3910 {
3911 if (pattrib->crc_err == 1)
3912 padapter->mppriv.rx_crcerrpktcount++;
3913 else
3914 padapter->mppriv.rx_pktcount++;
3915
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"));
3918 ret = _FAIL;
3919 rtw_free_recvframe(rframe, pfree_recv_queue);//free this recv_frame
3920 goto exit;
3921 }
3922 }
3923 #endif
3924
3925 //check the frame crtl field and decache
3926 ret = validate_recv_frame(padapter, rframe);
3927 if (ret != _SUCCESS)
3928 {
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
3931 goto exit;
3932 }
3933
3934 exit:
3935 return ret;
3936 }
3937
3938 static int recv_func_posthandle(_adapter *padapter, union recv_frame *prframe)
3939 {
3940 int ret = _SUCCESS;
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;
3945
3946 #ifdef CONFIG_MP_INCLUDED
3947 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
3948 #endif //CONFIG_MP_INCLUDED
3949
3950 #ifdef CONFIG_TDLS
3951 u8 *psnap_type, *pcategory;
3952 struct sta_info *ptdls_sta = NULL;
3953 #endif //CONFIG_TDLS
3954
3955
3956 // DATA FRAME
3957 rtw_led_control(padapter, LED_CTL_RX);
3958
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__);
3964 #endif
3965 ret = _FAIL;
3966 goto _recv_data_drop;
3967 }
3968
3969 #if 0
3970 if ( padapter->adapter_type == PRIMARY_ADAPTER )
3971 {
3972 DBG_871X("+++\n");
3973 {
3974 int i;
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));
3979
3980 }
3981 DBG_871X("---\n");
3982 }
3983 #endif //RTK_DMP_PLATFORM
3984
3985 #ifdef CONFIG_TDLS
3986 //check TDLS frame
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;
3990
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;
3995 }
3996 #endif //CONFIG_TDLS
3997
3998 prframe = recvframe_chk_defrag(padapter, prframe);
3999 if(prframe==NULL) {
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__);
4003 #endif
4004 goto _recv_data_drop;
4005 }
4006
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__);
4012 #endif
4013 ret = _FAIL;
4014 goto _recv_data_drop;
4015 }
4016
4017 #ifdef CONFIG_TDLS
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);
4021 #else
4022 count_rx_stats(padapter, prframe, NULL);
4023 #endif //CONFIG_TDLS
4024
4025 #ifdef CONFIG_80211N_HT
4026
4027 ret = process_recv_indicatepkts(padapter, prframe);
4028 if (ret != _SUCCESS)
4029 {
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__);
4033 #endif
4034 rtw_free_recvframe(orig_prframe, pfree_recv_queue);//free this recv_frame
4035 goto _recv_data_drop;
4036 }
4037
4038 #else // CONFIG_80211N_HT
4039
4040 if (!pattrib->amsdu)
4041 {
4042 ret = wlanhdr_to_ethhdr (prframe);
4043 if (ret != _SUCCESS)
4044 {
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__);
4048 #endif
4049 rtw_free_recvframe(orig_prframe, pfree_recv_queue);//free this recv_frame
4050 goto _recv_data_drop;
4051 }
4052
4053 if ((padapter->bDriverStopped == _FALSE) && (padapter->bSurpriseRemoved == _FALSE))
4054 {
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)
4059 {
4060 #ifdef DBG_RX_DROP_FRAME
4061 DBG_871X("DBG_RX_DROP_FRAME %s rtw_recv_indicatepkt fail!\n", __FUNCTION__);
4062 #endif
4063 goto _recv_data_drop;
4064 }
4065 }
4066 else
4067 {
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);
4073 #endif
4074 ret = _FAIL;
4075 rtw_free_recvframe(orig_prframe, pfree_recv_queue); //free this recv_frame
4076 }
4077
4078 }
4079 else if(pattrib->amsdu==1)
4080 {
4081
4082 ret = amsdu_to_msdu(padapter, prframe);
4083 if(ret != _SUCCESS)
4084 {
4085 #ifdef DBG_RX_DROP_FRAME
4086 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __FUNCTION__);
4087 #endif
4088 rtw_free_recvframe(orig_prframe, pfree_recv_queue);
4089 goto _recv_data_drop;
4090 }
4091 }
4092 else
4093 {
4094 #ifdef DBG_RX_DROP_FRAME
4095 DBG_871X("DBG_RX_DROP_FRAME %s what is this condition??\n", __FUNCTION__);
4096 #endif
4097 goto _recv_data_drop;
4098 }
4099 #endif // CONFIG_80211N_HT
4100
4101 _exit_recv_func:
4102 return ret;
4103
4104 _recv_data_drop:
4105 precvpriv->rx_drop++;
4106 return ret;
4107 }
4108
4109
4110 static int recv_func(_adapter *padapter, union recv_frame *rframe)
4111 {
4112 int ret;
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;
4117
4118 /* check if need to handle uc_swdec_pending_queue*/
4119 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey)
4120 {
4121 union recv_frame *pending_frame;
4122 _irqL irqL;
4123
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__);
4127 }
4128 }
4129
4130 ret = recv_func_prehandle(padapter, rframe);
4131
4132 if(ret == _SUCCESS) {
4133
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__);
4142 goto exit;
4143 }
4144
4145 ret = recv_func_posthandle(padapter, rframe);
4146 }
4147
4148 exit:
4149 return ret;
4150 }
4151
4152
4153 s32 rtw_recv_entry(union recv_frame *precvframe)
4154 {
4155 _adapter *padapter;
4156 struct recv_priv *precvpriv;
4157 s32 ret=_SUCCESS;
4158
4159 _func_enter_;
4160
4161 // RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("+rtw_recv_entry\n"));
4162
4163 padapter = precvframe->u.hdr.adapter;
4164
4165 precvpriv = &padapter->recvpriv;
4166
4167
4168 if ((ret = recv_func(padapter, precvframe)) == _FAIL)
4169 {
4170 RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("rtw_recv_entry: recv_func return fail!!!\n"));
4171 goto _recv_entry_drop;
4172 }
4173
4174
4175 precvpriv->rx_pkts++;
4176
4177 _func_exit_;
4178
4179 return ret;
4180
4181 _recv_entry_drop:
4182
4183 #ifdef CONFIG_MP_INCLUDED
4184 padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
4185 #endif
4186
4187 //RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("_recv_entry_drop\n"));
4188
4189 _func_exit_;
4190
4191 return ret;
4192 }
4193
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;
4198
4199 u32 tmp_s, tmp_q;
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
4205
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);
4210 } else {
4211
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;
4217 }
4218
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;
4224 }
4225
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
4229 ) {
4230 goto set_timer;
4231 }
4232 }
4233
4234 if(check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE
4235 || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == _FALSE
4236 ) {
4237 goto set_timer;
4238 }
4239
4240 #ifdef CONFIG_CONCURRENT_MODE
4241 if (check_buddy_fwstate(adapter, _FW_UNDER_SURVEY) == _TRUE)
4242 goto set_timer;
4243 #endif
4244
4245 //update value of signal_strength, rssi, signal_qual
4246 tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength);
4247 if(tmp_s %_alpha)
4248 tmp_s = tmp_s/_alpha + 1;
4249 else
4250 tmp_s = tmp_s/_alpha;
4251 if(tmp_s>100)
4252 tmp_s = 100;
4253
4254 tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual);
4255 if(tmp_q %_alpha)
4256 tmp_q = tmp_q/_alpha + 1;
4257 else
4258 tmp_q = tmp_q/_alpha;
4259 if(tmp_q>100)
4260 tmp_q = 100;
4261
4262 recvpriv->signal_strength = tmp_s;
4263 recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
4264 recvpriv->signal_qual = tmp_q;
4265
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"
4269 ", on_cur_ch_ms:%d"
4270 "\n"
4271 , FUNC_ADPT_ARG(adapter)
4272 , recvpriv->signal_strength
4273 , recvpriv->rssi
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
4277 );
4278 #endif
4279 }
4280
4281 set_timer:
4282 rtw_set_signal_stat_timer(recvpriv);
4283
4284 }
4285 #endif //CONFIG_NEW_SIGNAL_STAT_PROCESS