1 /****************************************************************************** 2 * 3 * Copyright(c) 2007 - 2012 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 ******************************************************************************/ 15 #define _RTW_RECV_C_ 16 17 #include <drv_types.h> 18 #include <rtw_debug.h> 19 #include <linux/jiffies.h> 20 #include <rtw_recv.h> 21 22 static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; 23 static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; 24 25 u8 rtw_rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; 26 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ 27 u8 rtw_bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; 28 29 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS); 30 31 void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) 32 { 33 memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); 34 35 spin_lock_init(&psta_recvpriv->lock); 36 37 /* for (i = 0; i<MAX_RX_NUMBLKS; i++) */ 38 /* _rtw_init_queue(&psta_recvpriv->blk_strms[i]); */ 39 40 _rtw_init_queue(&psta_recvpriv->defrag_q); 41 } 42 43 sint _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter) 44 { 45 sint i; 46 union recv_frame *precvframe; 47 sint res = _SUCCESS; 48 49 /* We don't need to memset padapter->XXX to zero, because adapter is allocated by vzalloc(). */ 50 /* memset((unsigned char *)precvpriv, 0, sizeof (struct recv_priv)); */ 51 52 spin_lock_init(&precvpriv->lock); 53 54 _rtw_init_queue(&precvpriv->free_recv_queue); 55 _rtw_init_queue(&precvpriv->recv_pending_queue); 56 _rtw_init_queue(&precvpriv->uc_swdec_pending_queue); 57 58 precvpriv->adapter = padapter; 59 60 precvpriv->free_recvframe_cnt = NR_RECVFRAME; 61 62 precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); 63 64 if (precvpriv->pallocated_frame_buf == NULL) { 65 res = _FAIL; 66 goto exit; 67 } 68 /* memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME * sizeof(union recv_frame) + RXFRAME_ALIGN_SZ); */ 69 70 precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ); 71 /* precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + RXFRAME_ALIGN_SZ - */ 72 /* ((SIZE_PTR) (precvpriv->pallocated_frame_buf) &(RXFRAME_ALIGN_SZ-1)); */ 73 74 precvframe = (union recv_frame *) precvpriv->precv_frame_buf; 75 76 77 for (i = 0; i < NR_RECVFRAME; i++) { 78 INIT_LIST_HEAD(&(precvframe->u.list)); 79 80 list_add_tail(&(precvframe->u.list), &(precvpriv->free_recv_queue.queue)); 81 82 res = rtw_os_recv_resource_alloc(padapter, precvframe); 83 84 precvframe->u.hdr.len = 0; 85 86 precvframe->u.hdr.adapter = padapter; 87 precvframe++; 88 89 } 90 91 res = rtw_hal_init_recv_priv(padapter); 92 93 rtw_init_timer(&precvpriv->signal_stat_timer, padapter, rtw_signal_stat_timer_hdl); 94 95 precvpriv->signal_stat_sampling_interval = 2000; /* ms */ 96 97 rtw_set_signal_stat_timer(precvpriv); 98 99 exit: 100 return res; 101 } 102 103 void _rtw_free_recv_priv(struct recv_priv *precvpriv) 104 { 105 struct adapter *padapter = precvpriv->adapter; 106 107 rtw_free_uc_swdec_pending_queue(padapter); 108 109 rtw_os_recv_resource_free(precvpriv); 110 111 if (precvpriv->pallocated_frame_buf) 112 vfree(precvpriv->pallocated_frame_buf); 113 114 rtw_hal_free_recv_priv(padapter); 115 } 116 117 union recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue) 118 { 119 120 union recv_frame *precvframe; 121 struct list_head *plist, *phead; 122 struct adapter *padapter; 123 struct recv_priv *precvpriv; 124 125 if (list_empty(&pfree_recv_queue->queue)) 126 precvframe = NULL; 127 else{ 128 phead = get_list_head(pfree_recv_queue); 129 130 plist = get_next(phead); 131 132 precvframe = LIST_CONTAINOR(plist, union recv_frame, u); 133 134 list_del_init(&precvframe->u.hdr.list); 135 padapter = precvframe->u.hdr.adapter; 136 if (padapter != NULL) { 137 precvpriv = &padapter->recvpriv; 138 if (pfree_recv_queue == &precvpriv->free_recv_queue) 139 precvpriv->free_recvframe_cnt--; 140 } 141 } 142 return precvframe; 143 } 144 145 union recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue) 146 { 147 union recv_frame *precvframe; 148 149 spin_lock_bh(&pfree_recv_queue->lock); 150 151 precvframe = _rtw_alloc_recvframe(pfree_recv_queue); 152 153 spin_unlock_bh(&pfree_recv_queue->lock); 154 155 return precvframe; 156 } 157 158 int rtw_free_recvframe(union recv_frame *precvframe, struct __queue *pfree_recv_queue) 159 { 160 struct adapter *padapter = precvframe->u.hdr.adapter; 161 struct recv_priv *precvpriv = &padapter->recvpriv; 162 163 rtw_os_free_recvframe(precvframe); 164 165 166 spin_lock_bh(&pfree_recv_queue->lock); 167 168 list_del_init(&(precvframe->u.hdr.list)); 169 170 precvframe->u.hdr.len = 0; 171 172 list_add_tail(&(precvframe->u.hdr.list), get_list_head(pfree_recv_queue)); 173 174 if (padapter != NULL) { 175 if (pfree_recv_queue == &precvpriv->free_recv_queue) 176 precvpriv->free_recvframe_cnt++; 177 } 178 spin_unlock_bh(&pfree_recv_queue->lock); 179 return _SUCCESS; 180 } 181 182 183 184 185 sint _rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue) 186 { 187 188 struct adapter *padapter = precvframe->u.hdr.adapter; 189 struct recv_priv *precvpriv = &padapter->recvpriv; 190 191 /* INIT_LIST_HEAD(&(precvframe->u.hdr.list)); */ 192 list_del_init(&(precvframe->u.hdr.list)); 193 194 195 list_add_tail(&(precvframe->u.hdr.list), get_list_head(queue)); 196 197 if (padapter != NULL) 198 if (queue == &precvpriv->free_recv_queue) 199 precvpriv->free_recvframe_cnt++; 200 201 return _SUCCESS; 202 } 203 204 sint rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue) 205 { 206 sint ret; 207 208 /* _spinlock(&pfree_recv_queue->lock); */ 209 spin_lock_bh(&queue->lock); 210 ret = _rtw_enqueue_recvframe(precvframe, queue); 211 /* spin_unlock(&pfree_recv_queue->lock); */ 212 spin_unlock_bh(&queue->lock); 213 214 return ret; 215 } 216 217 /* 218 sint rtw_enqueue_recvframe(union recv_frame *precvframe, struct __queue *queue) 219 { 220 return rtw_free_recvframe(precvframe, queue); 221 } 222 */ 223 224 225 226 227 /* 228 caller : defrag ; recvframe_chk_defrag in recv_thread (passive) 229 pframequeue: defrag_queue : will be accessed in recv_thread (passive) 230 231 using spinlock to protect 232 233 */ 234 235 void rtw_free_recvframe_queue(struct __queue *pframequeue, struct __queue *pfree_recv_queue) 236 { 237 union recv_frame *precvframe; 238 struct list_head *plist, *phead; 239 240 spin_lock(&pframequeue->lock); 241 242 phead = get_list_head(pframequeue); 243 plist = get_next(phead); 244 245 while (phead != plist) { 246 precvframe = LIST_CONTAINOR(plist, union recv_frame, u); 247 248 plist = get_next(plist); 249 250 rtw_free_recvframe(precvframe, pfree_recv_queue); 251 } 252 253 spin_unlock(&pframequeue->lock); 254 } 255 256 u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter) 257 { 258 u32 cnt = 0; 259 union recv_frame *pending_frame; 260 while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) { 261 rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue); 262 cnt++; 263 } 264 265 if (cnt) 266 DBG_871X(FUNC_ADPT_FMT" dequeue %d\n", FUNC_ADPT_ARG(adapter), cnt); 267 268 return cnt; 269 } 270 271 272 sint rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue) 273 { 274 spin_lock_bh(&queue->lock); 275 276 list_del_init(&precvbuf->list); 277 list_add(&precvbuf->list, get_list_head(queue)); 278 279 spin_unlock_bh(&queue->lock); 280 281 return _SUCCESS; 282 } 283 284 sint rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue) 285 { 286 spin_lock_bh(&queue->lock); 287 288 list_del_init(&precvbuf->list); 289 290 list_add_tail(&precvbuf->list, get_list_head(queue)); 291 spin_unlock_bh(&queue->lock); 292 return _SUCCESS; 293 294 } 295 296 struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue) 297 { 298 struct recv_buf *precvbuf; 299 struct list_head *plist, *phead; 300 301 spin_lock_bh(&queue->lock); 302 303 if (list_empty(&queue->queue)) 304 precvbuf = NULL; 305 else{ 306 phead = get_list_head(queue); 307 308 plist = get_next(phead); 309 310 precvbuf = LIST_CONTAINOR(plist, struct recv_buf, list); 311 312 list_del_init(&precvbuf->list); 313 314 } 315 316 spin_unlock_bh(&queue->lock); 317 318 return precvbuf; 319 320 } 321 322 sint recvframe_chkmic(struct adapter *adapter, union recv_frame *precvframe); 323 sint recvframe_chkmic(struct adapter *adapter, union recv_frame *precvframe) 324 { 325 326 sint i, res = _SUCCESS; 327 u32 datalen; 328 u8 miccode[8]; 329 u8 bmic_err = false, brpt_micerror = true; 330 u8 *pframe, *payload, *pframemic; 331 u8 *mickey; 332 /* u8 *iv, rxdata_key_idx = 0; */ 333 struct sta_info *stainfo; 334 struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib; 335 struct security_priv *psecuritypriv = &adapter->securitypriv; 336 337 struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv; 338 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info); 339 340 stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); 341 342 if (prxattrib->encrypt == _TKIP_) { 343 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic:prxattrib->encrypt == _TKIP_\n")); 344 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", 345 prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2], prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5])); 346 347 /* calculate mic code */ 348 if (stainfo != NULL) { 349 if (IS_MCAST(prxattrib->ra)) { 350 /* mickey =&psecuritypriv->dot118021XGrprxmickey.skey[0]; */ 351 /* iv = precvframe->u.hdr.rx_data+prxattrib->hdrlen; */ 352 /* rxdata_key_idx =(((iv[3])>>6)&0x3) ; */ 353 mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0]; 354 355 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n recvframe_chkmic: bcmc key\n")); 356 /* DBG_871X("\n recvframe_chkmic: bcmc key psecuritypriv->dot118021XGrpKeyid(%d), pmlmeinfo->key_index(%d) , recv key_id(%d)\n", */ 357 /* psecuritypriv->dot118021XGrpKeyid, pmlmeinfo->key_index, rxdata_key_idx); */ 358 359 if (psecuritypriv->binstallGrpkey == false) { 360 res = _FAIL; 361 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n")); 362 DBG_871X("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n"); 363 goto exit; 364 } 365 } else { 366 mickey = &stainfo->dot11tkiprxmickey.skey[0]; 367 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n recvframe_chkmic: unicast key\n")); 368 } 369 370 datalen = precvframe->u.hdr.len-prxattrib->hdrlen-prxattrib->iv_len-prxattrib->icv_len-8;/* icv_len included the mic code */ 371 pframe = precvframe->u.hdr.rx_data; 372 payload = pframe+prxattrib->hdrlen+prxattrib->iv_len; 373 374 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n prxattrib->iv_len =%d prxattrib->icv_len =%d\n", prxattrib->iv_len, prxattrib->icv_len)); 375 376 377 rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0], (unsigned char)prxattrib->priority); /* care the length of the data */ 378 379 pframemic = payload+datalen; 380 381 bmic_err = false; 382 383 for (i = 0; i < 8; i++) { 384 if (miccode[i] != *(pframemic+i)) { 385 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x) ", i, miccode[i], i, *(pframemic+i))); 386 bmic_err = true; 387 } 388 } 389 390 391 if (bmic_err == true) { 392 393 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", 394 *(pframemic-8), *(pframemic-7), *(pframemic-6), *(pframemic-5), *(pframemic-4), *(pframemic-3), *(pframemic-2), *(pframemic-1))); 395 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", 396 *(pframemic-16), *(pframemic-15), *(pframemic-14), *(pframemic-13), *(pframemic-12), *(pframemic-11), *(pframemic-10), *(pframemic-9))); 397 398 { 399 uint i; 400 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet (len =%d) ======\n", precvframe->u.hdr.len)); 401 for (i = 0; i < precvframe->u.hdr.len; i = i+8) { 402 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x", 403 *(precvframe->u.hdr.rx_data+i), *(precvframe->u.hdr.rx_data+i+1), 404 *(precvframe->u.hdr.rx_data+i+2), *(precvframe->u.hdr.rx_data+i+3), 405 *(precvframe->u.hdr.rx_data+i+4), *(precvframe->u.hdr.rx_data+i+5), 406 *(precvframe->u.hdr.rx_data+i+6), *(precvframe->u.hdr.rx_data+i+7))); 407 } 408 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n ======demp packet end [len =%d]======\n", precvframe->u.hdr.len)); 409 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("\n hrdlen =%d,\n", prxattrib->hdrlen)); 410 } 411 412 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ra = 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x psecuritypriv->binstallGrpkey =%d ", 413 prxattrib->ra[0], prxattrib->ra[1], prxattrib->ra[2], 414 prxattrib->ra[3], prxattrib->ra[4], prxattrib->ra[5], psecuritypriv->binstallGrpkey)); 415 416 /* double check key_index for some timing issue , */ 417 /* cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */ 418 if ((IS_MCAST(prxattrib->ra) == true) && (prxattrib->key_index != pmlmeinfo->key_index)) 419 brpt_micerror = false; 420 421 if ((prxattrib->bdecrypted == true) && (brpt_micerror == true)) { 422 rtw_handle_tkip_mic_err(adapter, (u8)IS_MCAST(prxattrib->ra)); 423 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted)); 424 DBG_871X(" mic error :prxattrib->bdecrypted =%d\n", prxattrib->bdecrypted); 425 } else{ 426 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" mic error :prxattrib->bdecrypted =%d ", prxattrib->bdecrypted)); 427 DBG_871X(" mic error :prxattrib->bdecrypted =%d\n", prxattrib->bdecrypted); 428 } 429 430 res = _FAIL; 431 432 } else { 433 /* mic checked ok */ 434 if ((psecuritypriv->bcheck_grpkey == false) && (IS_MCAST(prxattrib->ra) == true)) { 435 psecuritypriv->bcheck_grpkey = true; 436 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("psecuritypriv->bcheck_grpkey =true")); 437 } 438 } 439 440 } else 441 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic: rtw_get_stainfo == NULL!!!\n")); 442 443 recvframe_pull_tail(precvframe, 8); 444 445 } 446 447 exit: 448 return res; 449 450 } 451 452 /* decrypt and set the ivlen, icvlen of the recv_frame */ 453 union recv_frame *decryptor(struct adapter *padapter, union recv_frame *precv_frame); 454 union recv_frame *decryptor(struct adapter *padapter, union recv_frame *precv_frame) 455 { 456 457 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; 458 struct security_priv *psecuritypriv = &padapter->securitypriv; 459 union recv_frame *return_packet = precv_frame; 460 u32 res = _SUCCESS; 461 462 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt); 463 464 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n", prxattrib->bdecrypted, prxattrib->encrypt)); 465 466 if (prxattrib->encrypt > 0) { 467 u8 *iv = precv_frame->u.hdr.rx_data+prxattrib->hdrlen; 468 prxattrib->key_index = (((iv[3])>>6)&0x3); 469 470 if (prxattrib->key_index > WEP_KEYS) { 471 DBG_871X("prxattrib->key_index(%d) > WEP_KEYS\n", prxattrib->key_index); 472 473 switch (prxattrib->encrypt) { 474 case _WEP40_: 475 case _WEP104_: 476 prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex; 477 break; 478 case _TKIP_: 479 case _AES_: 480 default: 481 prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid; 482 break; 483 } 484 } 485 } 486 487 if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt == true))) { 488 psecuritypriv->hw_decrypted = false; 489 490 #ifdef DBG_RX_DECRYPTOR 491 DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n", 492 __func__, 493 __LINE__, 494 prxattrib->bdecrypted, 495 prxattrib->encrypt, 496 psecuritypriv->hw_decrypted); 497 #endif 498 499 switch (prxattrib->encrypt) { 500 case _WEP40_: 501 case _WEP104_: 502 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_wep); 503 rtw_wep_decrypt(padapter, (u8 *)precv_frame); 504 break; 505 case _TKIP_: 506 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_tkip); 507 res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame); 508 break; 509 case _AES_: 510 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_aes); 511 res = rtw_aes_decrypt(padapter, (u8 *)precv_frame); 512 break; 513 default: 514 break; 515 } 516 } else if (prxattrib->bdecrypted == 1 517 && prxattrib->encrypt > 0 518 && (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_) 519 ) { 520 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_hw); 521 522 psecuritypriv->hw_decrypted = true; 523 #ifdef DBG_RX_DECRYPTOR 524 DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n", 525 __func__, 526 __LINE__, 527 prxattrib->bdecrypted, 528 prxattrib->encrypt, 529 psecuritypriv->hw_decrypted); 530 531 #endif 532 } else { 533 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_unknown); 534 #ifdef DBG_RX_DECRYPTOR 535 DBG_871X("[%s] %d:prxstat->bdecrypted:%d, prxattrib->encrypt:%d, Setting psecuritypriv->hw_decrypted = %d\n", 536 __func__, 537 __LINE__, 538 prxattrib->bdecrypted, 539 prxattrib->encrypt, 540 psecuritypriv->hw_decrypted); 541 #endif 542 } 543 544 if (res == _FAIL) { 545 rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue); 546 return_packet = NULL; 547 } else 548 prxattrib->bdecrypted = true; 549 550 return return_packet; 551 } 552 553 /* set the security information in the recv_frame */ 554 union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame); 555 union recv_frame *portctrl(struct adapter *adapter, union recv_frame *precv_frame) 556 { 557 u8 *psta_addr = NULL; 558 u8 *ptr; 559 uint auth_alg; 560 struct recv_frame_hdr *pfhdr; 561 struct sta_info *psta; 562 struct sta_priv *pstapriv; 563 union recv_frame *prtnframe; 564 u16 ether_type = 0; 565 u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */ 566 struct rx_pkt_attrib *pattrib; 567 568 pstapriv = &adapter->stapriv; 569 570 auth_alg = adapter->securitypriv.dot11AuthAlgrthm; 571 572 ptr = get_recvframe_data(precv_frame); 573 pfhdr = &precv_frame->u.hdr; 574 pattrib = &pfhdr->attrib; 575 psta_addr = pattrib->ta; 576 577 prtnframe = NULL; 578 579 psta = rtw_get_stainfo(pstapriv, psta_addr); 580 581 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm =%d\n", adapter->securitypriv.dot11AuthAlgrthm)); 582 583 if (auth_alg == 2) { 584 if ((psta != NULL) && (psta->ieee8021x_blocked)) { 585 __be16 be_tmp; 586 587 /* blocked */ 588 /* only accept EAPOL frame */ 589 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked == 1\n")); 590 591 prtnframe = precv_frame; 592 593 /* get ether_type */ 594 ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE; 595 memcpy(&be_tmp, ptr, 2); 596 ether_type = ntohs(be_tmp); 597 598 if (ether_type == eapol_type) 599 prtnframe = precv_frame; 600 else { 601 /* free this frame */ 602 rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue); 603 prtnframe = NULL; 604 } 605 } else{ 606 /* allowed */ 607 /* check decryption status, and decrypt the frame if needed */ 608 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked == 0\n")); 609 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:precv_frame->hdr.attrib.privacy =%x\n", precv_frame->u.hdr.attrib.privacy)); 610 611 if (pattrib->bdecrypted == 0) 612 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("portctrl:prxstat->decrypted =%x\n", pattrib->bdecrypted)); 613 614 prtnframe = precv_frame; 615 /* check is the EAPOL frame or not (Rekey) */ 616 /* if (ether_type == eapol_type) { */ 617 /* RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("########portctrl:ether_type == 0x888e\n")); */ 618 /* check Rekey */ 619 620 /* prtnframe =precv_frame; */ 621 /* */ 622 /* else { */ 623 /* RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:ether_type = 0x%04x\n", ether_type)); */ 624 /* */ 625 } 626 } else 627 prtnframe = precv_frame; 628 629 return prtnframe; 630 } 631 632 sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache); 633 sint recv_decache(union recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache) 634 { 635 sint tid = precv_frame->u.hdr.attrib.priority; 636 637 u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num&0xffff) << 4) | 638 (precv_frame->u.hdr.attrib.frag_num & 0xf); 639 640 if (tid > 15) { 641 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n", seq_ctrl, tid)); 642 643 return _FAIL; 644 } 645 646 if (1) { /* if (bretry) */ 647 if (seq_ctrl == prxcache->tid_rxseq[tid]) { 648 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])); 649 650 return _FAIL; 651 } 652 } 653 654 prxcache->tid_rxseq[tid] = seq_ctrl; 655 656 return _SUCCESS; 657 658 } 659 660 void process_pwrbit_data(struct adapter *padapter, union recv_frame *precv_frame); 661 void process_pwrbit_data(struct adapter *padapter, union recv_frame *precv_frame) 662 { 663 unsigned char pwrbit; 664 u8 *ptr = precv_frame->u.hdr.rx_data; 665 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 666 struct sta_priv *pstapriv = &padapter->stapriv; 667 struct sta_info *psta = NULL; 668 669 psta = rtw_get_stainfo(pstapriv, pattrib->src); 670 671 pwrbit = GetPwrMgt(ptr); 672 673 if (psta) { 674 if (pwrbit) { 675 if (!(psta->state & WIFI_SLEEP_STATE)) { 676 /* psta->state |= WIFI_SLEEP_STATE; */ 677 /* pstapriv->sta_dz_bitmap |= BIT(psta->aid); */ 678 679 stop_sta_xmit(padapter, psta); 680 681 /* DBG_871X("to sleep, sta_dz_bitmap =%x\n", pstapriv->sta_dz_bitmap); */ 682 } 683 } else{ 684 if (psta->state & WIFI_SLEEP_STATE) { 685 /* psta->state ^= WIFI_SLEEP_STATE; */ 686 /* pstapriv->sta_dz_bitmap &= ~BIT(psta->aid); */ 687 688 wakeup_sta_to_xmit(padapter, psta); 689 690 /* DBG_871X("to wakeup, sta_dz_bitmap =%x\n", pstapriv->sta_dz_bitmap); */ 691 } 692 } 693 694 } 695 } 696 697 void process_wmmps_data(struct adapter *padapter, union recv_frame *precv_frame); 698 void process_wmmps_data(struct adapter *padapter, union recv_frame *precv_frame) 699 { 700 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 701 struct sta_priv *pstapriv = &padapter->stapriv; 702 struct sta_info *psta = NULL; 703 704 psta = rtw_get_stainfo(pstapriv, pattrib->src); 705 706 if (!psta) 707 return; 708 709 if (!psta->qos_option) 710 return; 711 712 if (!(psta->qos_info&0xf)) 713 return; 714 715 if (psta->state&WIFI_SLEEP_STATE) { 716 u8 wmmps_ac = 0; 717 718 switch (pattrib->priority) { 719 case 1: 720 case 2: 721 wmmps_ac = psta->uapsd_bk&BIT(1); 722 break; 723 case 4: 724 case 5: 725 wmmps_ac = psta->uapsd_vi&BIT(1); 726 break; 727 case 6: 728 case 7: 729 wmmps_ac = psta->uapsd_vo&BIT(1); 730 break; 731 case 0: 732 case 3: 733 default: 734 wmmps_ac = psta->uapsd_be&BIT(1); 735 break; 736 } 737 738 if (wmmps_ac) { 739 if (psta->sleepq_ac_len > 0) 740 /* process received triggered frame */ 741 xmit_delivery_enabled_frames(padapter, psta); 742 else 743 /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */ 744 issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0); 745 } 746 } 747 } 748 749 void count_rx_stats(struct adapter *padapter, union recv_frame *prframe, struct sta_info *sta); 750 void count_rx_stats(struct adapter *padapter, union recv_frame *prframe, struct sta_info *sta) 751 { 752 int sz; 753 struct sta_info *psta = NULL; 754 struct stainfo_stats *pstats = NULL; 755 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; 756 struct recv_priv *precvpriv = &padapter->recvpriv; 757 758 sz = get_recvframe_len(prframe); 759 precvpriv->rx_bytes += sz; 760 761 padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++; 762 763 if ((!MacAddr_isBcst(pattrib->dst)) && (!IS_MCAST(pattrib->dst))) { 764 padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++; 765 } 766 767 if (sta) 768 psta = sta; 769 else 770 psta = prframe->u.hdr.psta; 771 772 if (psta) { 773 pstats = &psta->sta_stats; 774 775 pstats->rx_data_pkts++; 776 pstats->rx_bytes += sz; 777 } 778 779 traffic_check_for_leave_lps(padapter, false, 0); 780 } 781 782 sint sta2sta_data_frame( 783 struct adapter *adapter, 784 union recv_frame *precv_frame, 785 struct sta_info **psta 786 ); 787 sint sta2sta_data_frame( 788 struct adapter *adapter, 789 union recv_frame *precv_frame, 790 struct sta_info **psta 791 ) 792 { 793 u8 *ptr = precv_frame->u.hdr.rx_data; 794 sint ret = _SUCCESS; 795 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 796 struct sta_priv *pstapriv = &adapter->stapriv; 797 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 798 u8 *mybssid = get_bssid(pmlmepriv); 799 u8 *myhwaddr = myid(&adapter->eeprompriv); 800 u8 *sta_addr = NULL; 801 sint bmcast = IS_MCAST(pattrib->dst); 802 803 /* DBG_871X("[%s] %d, seqnum:%d\n", __func__, __LINE__, pattrib->seq_num); */ 804 805 if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) || 806 (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) { 807 808 /* filter packets that SA is myself or multicast or broadcast */ 809 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { 810 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA ==myself\n")); 811 ret = _FAIL; 812 goto exit; 813 } 814 815 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { 816 ret = _FAIL; 817 goto exit; 818 } 819 820 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || 821 !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || 822 (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { 823 ret = _FAIL; 824 goto exit; 825 } 826 827 sta_addr = pattrib->src; 828 829 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) { 830 /* For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */ 831 if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) { 832 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("bssid != TA under STATION_MODE; drop pkt\n")); 833 ret = _FAIL; 834 goto exit; 835 } 836 837 sta_addr = pattrib->bssid; 838 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 839 if (bmcast) { 840 /* For AP mode, if DA == MCAST, then BSSID should be also MCAST */ 841 if (!IS_MCAST(pattrib->bssid)) { 842 ret = _FAIL; 843 goto exit; 844 } 845 } else{ /* not mc-frame */ 846 /* For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */ 847 if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) { 848 ret = _FAIL; 849 goto exit; 850 } 851 852 sta_addr = pattrib->src; 853 } 854 855 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) { 856 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); 857 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); 858 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); 859 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); 860 memcpy(pattrib->ta, pattrib->src, ETH_ALEN); 861 862 sta_addr = mybssid; 863 } else 864 ret = _FAIL; 865 866 867 868 if (bmcast) 869 *psta = rtw_get_bcmc_stainfo(adapter); 870 else 871 *psta = rtw_get_stainfo(pstapriv, sta_addr); /* get ap_info */ 872 873 if (*psta == NULL) { 874 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under sta2sta_data_frame ; drop pkt\n")); 875 ret = _FAIL; 876 goto exit; 877 } 878 879 exit: 880 return ret; 881 } 882 883 sint ap2sta_data_frame( 884 struct adapter *adapter, 885 union recv_frame *precv_frame, 886 struct sta_info **psta); 887 sint ap2sta_data_frame( 888 struct adapter *adapter, 889 union recv_frame *precv_frame, 890 struct sta_info **psta) 891 { 892 u8 *ptr = precv_frame->u.hdr.rx_data; 893 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 894 sint ret = _SUCCESS; 895 struct sta_priv *pstapriv = &adapter->stapriv; 896 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 897 u8 *mybssid = get_bssid(pmlmepriv); 898 u8 *myhwaddr = myid(&adapter->eeprompriv); 899 sint bmcast = IS_MCAST(pattrib->dst); 900 901 if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true) 902 && (check_fwstate(pmlmepriv, _FW_LINKED) == true 903 || check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) 904 ) { 905 906 /* filter packets that SA is myself or multicast or broadcast */ 907 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) { 908 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" SA ==myself\n")); 909 #ifdef DBG_RX_DROP_FRAME 910 DBG_871X("DBG_RX_DROP_FRAME %s SA ="MAC_FMT", myhwaddr ="MAC_FMT"\n", 911 __func__, MAC_ARG(pattrib->src), MAC_ARG(myhwaddr)); 912 #endif 913 ret = _FAIL; 914 goto exit; 915 } 916 917 /* da should be for me */ 918 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) { 919 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, 920 (" ap2sta_data_frame: compare DA fail; DA ="MAC_FMT"\n", MAC_ARG(pattrib->dst))); 921 #ifdef DBG_RX_DROP_FRAME 922 DBG_871X("DBG_RX_DROP_FRAME %s DA ="MAC_FMT"\n", __func__, MAC_ARG(pattrib->dst)); 923 #endif 924 ret = _FAIL; 925 goto exit; 926 } 927 928 929 /* check BSSID */ 930 if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || 931 !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) || 932 (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) { 933 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, 934 (" ap2sta_data_frame: compare BSSID fail ; BSSID ="MAC_FMT"\n", MAC_ARG(pattrib->bssid))); 935 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("mybssid ="MAC_FMT"\n", MAC_ARG(mybssid))); 936 #ifdef DBG_RX_DROP_FRAME 937 DBG_871X("DBG_RX_DROP_FRAME %s BSSID ="MAC_FMT", mybssid ="MAC_FMT"\n", 938 __func__, MAC_ARG(pattrib->bssid), MAC_ARG(mybssid)); 939 DBG_871X("this adapter = %d, buddy adapter = %d\n", adapter->adapter_type, adapter->pbuddystruct adapter->adapter_type); 940 #endif 941 942 if (!bmcast) { 943 DBG_871X("issue_deauth to the nonassociated ap =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid)); 944 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 945 } 946 947 ret = _FAIL; 948 goto exit; 949 } 950 951 if (bmcast) 952 *psta = rtw_get_bcmc_stainfo(adapter); 953 else 954 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get ap_info */ 955 956 if (*psta == NULL) { 957 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("ap2sta: can't get psta under STATION_MODE ; drop pkt\n")); 958 #ifdef DBG_RX_DROP_FRAME 959 DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under STATION_MODE ; drop pkt\n", __func__); 960 #endif 961 ret = _FAIL; 962 goto exit; 963 } 964 965 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { 966 } 967 968 if (GetFrameSubType(ptr) & BIT(6)) { 969 /* No data, will not indicate to upper layer, temporily count it here */ 970 count_rx_stats(adapter, precv_frame, *psta); 971 ret = RTW_RX_HANDLED; 972 goto exit; 973 } 974 975 } else if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) && 976 (check_fwstate(pmlmepriv, _FW_LINKED) == true)) { 977 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); 978 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); 979 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); 980 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); 981 memcpy(pattrib->ta, pattrib->src, ETH_ALEN); 982 983 /* */ 984 memcpy(pattrib->bssid, mybssid, ETH_ALEN); 985 986 987 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ 988 if (*psta == NULL) { 989 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under MP_MODE ; drop pkt\n")); 990 #ifdef DBG_RX_DROP_FRAME 991 DBG_871X("DBG_RX_DROP_FRAME %s can't get psta under WIFI_MP_STATE ; drop pkt\n", __func__); 992 #endif 993 ret = _FAIL; 994 goto exit; 995 } 996 997 998 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 999 /* Special case */ 1000 ret = RTW_RX_HANDLED; 1001 goto exit; 1002 } else{ 1003 if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) { 1004 *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /* get sta_info */ 1005 if (*psta == NULL) { 1006 1007 /* for AP multicast issue , modify by yiwei */ 1008 static unsigned long send_issue_deauth_time = 0; 1009 1010 /* DBG_871X("After send deauth , %u ms has elapsed.\n", jiffies_to_msecs(jiffies - send_issue_deauth_time)); */ 1011 1012 if (jiffies_to_msecs(jiffies - send_issue_deauth_time) > 10000 || send_issue_deauth_time == 0) { 1013 send_issue_deauth_time = jiffies; 1014 1015 DBG_871X("issue_deauth to the ap =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->bssid)); 1016 1017 issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 1018 } 1019 } 1020 } 1021 1022 ret = _FAIL; 1023 #ifdef DBG_RX_DROP_FRAME 1024 DBG_871X("DBG_RX_DROP_FRAME %s fw_state:0x%x\n", __func__, get_fwstate(pmlmepriv)); 1025 #endif 1026 } 1027 1028 exit: 1029 return ret; 1030 } 1031 1032 sint sta2ap_data_frame( 1033 struct adapter *adapter, 1034 union recv_frame *precv_frame, 1035 struct sta_info **psta); 1036 sint sta2ap_data_frame( 1037 struct adapter *adapter, 1038 union recv_frame *precv_frame, 1039 struct sta_info **psta) 1040 { 1041 u8 *ptr = precv_frame->u.hdr.rx_data; 1042 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 1043 struct sta_priv *pstapriv = &adapter->stapriv; 1044 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1045 unsigned char *mybssid = get_bssid(pmlmepriv); 1046 sint ret = _SUCCESS; 1047 1048 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) { 1049 /* For AP mode, RA =BSSID, TX =STA(SRC_ADDR), A3 =DST_ADDR */ 1050 if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) { 1051 ret = _FAIL; 1052 goto exit; 1053 } 1054 1055 *psta = rtw_get_stainfo(pstapriv, pattrib->src); 1056 if (*psta == NULL) { 1057 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("can't get psta under AP_MODE; drop pkt\n")); 1058 DBG_871X("issue_deauth to sta =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); 1059 1060 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 1061 1062 ret = RTW_RX_HANDLED; 1063 goto exit; 1064 } 1065 1066 process_pwrbit_data(adapter, precv_frame); 1067 1068 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { 1069 process_wmmps_data(adapter, precv_frame); 1070 } 1071 1072 if (GetFrameSubType(ptr) & BIT(6)) { 1073 /* No data, will not indicate to upper layer, temporily count it here */ 1074 count_rx_stats(adapter, precv_frame, *psta); 1075 ret = RTW_RX_HANDLED; 1076 goto exit; 1077 } 1078 } else { 1079 u8 *myhwaddr = myid(&adapter->eeprompriv); 1080 if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) { 1081 ret = RTW_RX_HANDLED; 1082 goto exit; 1083 } 1084 DBG_871X("issue_deauth to sta =" MAC_FMT " for the reason(7)\n", MAC_ARG(pattrib->src)); 1085 issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA); 1086 ret = RTW_RX_HANDLED; 1087 goto exit; 1088 } 1089 1090 exit: 1091 return ret; 1092 } 1093 1094 sint validate_recv_ctrl_frame(struct adapter *padapter, union recv_frame *precv_frame); 1095 sint validate_recv_ctrl_frame(struct adapter *padapter, union recv_frame *precv_frame) 1096 { 1097 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 1098 struct sta_priv *pstapriv = &padapter->stapriv; 1099 u8 *pframe = precv_frame->u.hdr.rx_data; 1100 struct sta_info *psta = NULL; 1101 /* uint len = precv_frame->u.hdr.len; */ 1102 1103 /* DBG_871X("+validate_recv_ctrl_frame\n"); */ 1104 1105 if (GetFrameType(pframe) != WIFI_CTRL_TYPE) 1106 return _FAIL; 1107 1108 /* receive the frames that ra(a1) is my address */ 1109 if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN)) 1110 return _FAIL; 1111 1112 psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe)); 1113 if (psta == NULL) 1114 return _FAIL; 1115 1116 /* for rx pkt statistics */ 1117 psta->sta_stats.rx_ctrl_pkts++; 1118 1119 /* only handle ps-poll */ 1120 if (GetFrameSubType(pframe) == WIFI_PSPOLL) { 1121 u16 aid; 1122 u8 wmmps_ac = 0; 1123 1124 aid = GetAid(pframe); 1125 if (psta->aid != aid) 1126 return _FAIL; 1127 1128 switch (pattrib->priority) { 1129 case 1: 1130 case 2: 1131 wmmps_ac = psta->uapsd_bk&BIT(0); 1132 break; 1133 case 4: 1134 case 5: 1135 wmmps_ac = psta->uapsd_vi&BIT(0); 1136 break; 1137 case 6: 1138 case 7: 1139 wmmps_ac = psta->uapsd_vo&BIT(0); 1140 break; 1141 case 0: 1142 case 3: 1143 default: 1144 wmmps_ac = psta->uapsd_be&BIT(0); 1145 break; 1146 } 1147 1148 if (wmmps_ac) 1149 return _FAIL; 1150 1151 if (psta->state & WIFI_STA_ALIVE_CHK_STATE) { 1152 DBG_871X("%s alive check-rx ps-poll\n", __func__); 1153 psta->expire_to = pstapriv->expire_to; 1154 psta->state ^= WIFI_STA_ALIVE_CHK_STATE; 1155 } 1156 1157 if ((psta->state&WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap&BIT(psta->aid))) { 1158 struct list_head *xmitframe_plist, *xmitframe_phead; 1159 struct xmit_frame *pxmitframe = NULL; 1160 struct xmit_priv *pxmitpriv = &padapter->xmitpriv; 1161 1162 /* spin_lock_bh(&psta->sleep_q.lock); */ 1163 spin_lock_bh(&pxmitpriv->lock); 1164 1165 xmitframe_phead = get_list_head(&psta->sleep_q); 1166 xmitframe_plist = get_next(xmitframe_phead); 1167 1168 if (xmitframe_phead != xmitframe_plist) { 1169 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list); 1170 1171 xmitframe_plist = get_next(xmitframe_plist); 1172 1173 list_del_init(&pxmitframe->list); 1174 1175 psta->sleepq_len--; 1176 1177 if (psta->sleepq_len > 0) 1178 pxmitframe->attrib.mdata = 1; 1179 else 1180 pxmitframe->attrib.mdata = 0; 1181 1182 pxmitframe->attrib.triggered = 1; 1183 1184 /* DBG_871X("handling ps-poll, q_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */ 1185 1186 rtw_hal_xmitframe_enqueue(padapter, pxmitframe); 1187 1188 if (psta->sleepq_len == 0) { 1189 pstapriv->tim_bitmap &= ~BIT(psta->aid); 1190 1191 /* DBG_871X("after handling ps-poll, tim =%x\n", pstapriv->tim_bitmap); */ 1192 1193 /* upate BCN for TIM IE */ 1194 /* update_BCNTIM(padapter); */ 1195 update_beacon(padapter, _TIM_IE_, NULL, true); 1196 } 1197 1198 /* spin_unlock_bh(&psta->sleep_q.lock); */ 1199 spin_unlock_bh(&pxmitpriv->lock); 1200 1201 } else{ 1202 /* spin_unlock_bh(&psta->sleep_q.lock); */ 1203 spin_unlock_bh(&pxmitpriv->lock); 1204 1205 /* DBG_871X("no buffered packets to xmit\n"); */ 1206 if (pstapriv->tim_bitmap&BIT(psta->aid)) { 1207 if (psta->sleepq_len == 0) { 1208 DBG_871X("no buffered packets to xmit\n"); 1209 1210 /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */ 1211 issue_nulldata_in_interrupt(padapter, psta->hwaddr); 1212 } else{ 1213 DBG_871X("error!psta->sleepq_len =%d\n", psta->sleepq_len); 1214 psta->sleepq_len = 0; 1215 } 1216 1217 pstapriv->tim_bitmap &= ~BIT(psta->aid); 1218 1219 /* upate BCN for TIM IE */ 1220 /* update_BCNTIM(padapter); */ 1221 update_beacon(padapter, _TIM_IE_, NULL, true); 1222 } 1223 } 1224 } 1225 } 1226 1227 return _FAIL; 1228 1229 } 1230 1231 union recv_frame *recvframe_chk_defrag(struct adapter *padapter, union recv_frame *precv_frame); 1232 sint validate_recv_mgnt_frame(struct adapter *padapter, union recv_frame *precv_frame); 1233 sint validate_recv_mgnt_frame(struct adapter *padapter, union recv_frame *precv_frame) 1234 { 1235 /* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */ 1236 1237 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+validate_recv_mgnt_frame\n")); 1238 1239 precv_frame = recvframe_chk_defrag(padapter, precv_frame); 1240 if (precv_frame == NULL) { 1241 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("%s: fragment packet\n", __func__)); 1242 return _SUCCESS; 1243 } 1244 1245 { 1246 /* for rx pkt statistics */ 1247 struct sta_info *psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->u.hdr.rx_data)); 1248 if (psta) { 1249 psta->sta_stats.rx_mgnt_pkts++; 1250 if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_BEACON) 1251 psta->sta_stats.rx_beacon_pkts++; 1252 else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBEREQ) 1253 psta->sta_stats.rx_probereq_pkts++; 1254 else if (GetFrameSubType(precv_frame->u.hdr.rx_data) == WIFI_PROBERSP) { 1255 if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->u.hdr.rx_data), ETH_ALEN)) 1256 psta->sta_stats.rx_probersp_pkts++; 1257 else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data)) 1258 || is_multicast_mac_addr(GetAddr1Ptr(precv_frame->u.hdr.rx_data))) 1259 psta->sta_stats.rx_probersp_bm_pkts++; 1260 else 1261 psta->sta_stats.rx_probersp_uo_pkts++; 1262 } 1263 } 1264 } 1265 1266 mgt_dispatcher(padapter, precv_frame); 1267 1268 return _SUCCESS; 1269 1270 } 1271 1272 sint validate_recv_data_frame(struct adapter *adapter, union recv_frame *precv_frame); 1273 sint validate_recv_data_frame(struct adapter *adapter, union recv_frame *precv_frame) 1274 { 1275 u8 bretry; 1276 u8 *psa, *pda, *pbssid; 1277 struct sta_info *psta = NULL; 1278 u8 *ptr = precv_frame->u.hdr.rx_data; 1279 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 1280 struct security_priv *psecuritypriv = &adapter->securitypriv; 1281 sint ret = _SUCCESS; 1282 1283 bretry = GetRetry(ptr); 1284 pda = get_da(ptr); 1285 psa = get_sa(ptr); 1286 pbssid = get_hdr_bssid(ptr); 1287 1288 if (pbssid == NULL) { 1289 #ifdef DBG_RX_DROP_FRAME 1290 DBG_871X("DBG_RX_DROP_FRAME %s pbssid == NULL\n", __func__); 1291 #endif 1292 ret = _FAIL; 1293 goto exit; 1294 } 1295 1296 memcpy(pattrib->dst, pda, ETH_ALEN); 1297 memcpy(pattrib->src, psa, ETH_ALEN); 1298 1299 memcpy(pattrib->bssid, pbssid, ETH_ALEN); 1300 1301 switch (pattrib->to_fr_ds) { 1302 case 0: 1303 memcpy(pattrib->ra, pda, ETH_ALEN); 1304 memcpy(pattrib->ta, psa, ETH_ALEN); 1305 ret = sta2sta_data_frame(adapter, precv_frame, &psta); 1306 break; 1307 1308 case 1: 1309 memcpy(pattrib->ra, pda, ETH_ALEN); 1310 memcpy(pattrib->ta, pbssid, ETH_ALEN); 1311 ret = ap2sta_data_frame(adapter, precv_frame, &psta); 1312 break; 1313 1314 case 2: 1315 memcpy(pattrib->ra, pbssid, ETH_ALEN); 1316 memcpy(pattrib->ta, psa, ETH_ALEN); 1317 ret = sta2ap_data_frame(adapter, precv_frame, &psta); 1318 break; 1319 1320 case 3: 1321 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); 1322 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); 1323 ret = _FAIL; 1324 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" case 3\n")); 1325 break; 1326 1327 default: 1328 ret = _FAIL; 1329 break; 1330 1331 } 1332 1333 if (ret == _FAIL) { 1334 #ifdef DBG_RX_DROP_FRAME 1335 DBG_871X("DBG_RX_DROP_FRAME %s case:%d, res:%d\n", __func__, pattrib->to_fr_ds, ret); 1336 #endif 1337 goto exit; 1338 } else if (ret == RTW_RX_HANDLED) { 1339 goto exit; 1340 } 1341 1342 1343 if (psta == NULL) { 1344 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, (" after to_fr_ds_chk; psta == NULL\n")); 1345 #ifdef DBG_RX_DROP_FRAME 1346 DBG_871X("DBG_RX_DROP_FRAME %s psta == NULL\n", __func__); 1347 #endif 1348 ret = _FAIL; 1349 goto exit; 1350 } 1351 1352 /* psta->rssi = prxcmd->rssi; */ 1353 /* psta->signal_quality = prxcmd->sq; */ 1354 precv_frame->u.hdr.psta = psta; 1355 1356 1357 pattrib->amsdu = 0; 1358 pattrib->ack_policy = 0; 1359 /* parsing QC field */ 1360 if (pattrib->qos == 1) { 1361 pattrib->priority = GetPriority((ptr + 24)); 1362 pattrib->ack_policy = GetAckpolicy((ptr + 24)); 1363 pattrib->amsdu = GetAMsdu((ptr + 24)); 1364 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; 1365 1366 if (pattrib->priority != 0 && pattrib->priority != 3) 1367 adapter->recvpriv.bIsAnyNonBEPkts = true; 1368 1369 } else{ 1370 pattrib->priority = 0; 1371 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24; 1372 } 1373 1374 1375 if (pattrib->order)/* HT-CTRL 11n */ 1376 pattrib->hdrlen += 4; 1377 1378 precv_frame->u.hdr.preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority]; 1379 1380 /* decache, drop duplicate recv packets */ 1381 if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) { 1382 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decache : drop pkt\n")); 1383 #ifdef DBG_RX_DROP_FRAME 1384 DBG_871X("DBG_RX_DROP_FRAME %s recv_decache return _FAIL\n", __func__); 1385 #endif 1386 ret = _FAIL; 1387 goto exit; 1388 } 1389 1390 if (pattrib->privacy) { 1391 1392 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("validate_recv_data_frame:pattrib->privacy =%x\n", pattrib->privacy)); 1393 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))); 1394 1395 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, IS_MCAST(pattrib->ra)); 1396 1397 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n pattrib->encrypt =%d\n", pattrib->encrypt)); 1398 1399 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); 1400 } else{ 1401 pattrib->encrypt = 0; 1402 pattrib->iv_len = pattrib->icv_len = 0; 1403 } 1404 1405 exit: 1406 return ret; 1407 } 1408 1409 static sint validate_80211w_mgmt(struct adapter *adapter, union recv_frame *precv_frame) 1410 { 1411 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1412 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 1413 u8 *ptr = precv_frame->u.hdr.rx_data; 1414 u8 type; 1415 u8 subtype; 1416 1417 type = GetFrameType(ptr); 1418 subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */ 1419 1420 /* only support station mode */ 1421 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && check_fwstate(pmlmepriv, _FW_LINKED) 1422 && adapter->securitypriv.binstallBIPkey == true) { 1423 /* unicast management frame decrypt */ 1424 if (pattrib->privacy && !(IS_MCAST(GetAddr1Ptr(ptr))) && 1425 (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC || subtype == WIFI_ACTION)) { 1426 u8 *ppp, *mgmt_DATA; 1427 u32 data_len = 0; 1428 ppp = GetAddr2Ptr(ptr); 1429 1430 pattrib->bdecrypted = 0; 1431 pattrib->encrypt = _AES_; 1432 pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr); 1433 /* set iv and icv length */ 1434 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt); 1435 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); 1436 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); 1437 /* actual management data frame body */ 1438 data_len = pattrib->pkt_len - pattrib->hdrlen - pattrib->iv_len - pattrib->icv_len; 1439 mgmt_DATA = rtw_zmalloc(data_len); 1440 if (mgmt_DATA == NULL) { 1441 DBG_871X("%s mgmt allocate fail !!!!!!!!!\n", __func__); 1442 goto validate_80211w_fail; 1443 } 1444 precv_frame = decryptor(adapter, precv_frame); 1445 /* save actual management data frame body */ 1446 memcpy(mgmt_DATA, ptr+pattrib->hdrlen+pattrib->iv_len, data_len); 1447 /* overwrite the iv field */ 1448 memcpy(ptr+pattrib->hdrlen, mgmt_DATA, data_len); 1449 /* remove the iv and icv length */ 1450 pattrib->pkt_len = pattrib->pkt_len - pattrib->iv_len - pattrib->icv_len; 1451 kfree(mgmt_DATA); 1452 if (!precv_frame) { 1453 DBG_871X("%s mgmt descrypt fail !!!!!!!!!\n", __func__); 1454 goto validate_80211w_fail; 1455 } 1456 } else if (IS_MCAST(GetAddr1Ptr(ptr)) && 1457 (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC)) { 1458 sint BIP_ret = _SUCCESS; 1459 /* verify BIP MME IE of broadcast/multicast de-auth/disassoc packet */ 1460 BIP_ret = rtw_BIP_verify(adapter, (u8 *)precv_frame); 1461 if (BIP_ret == _FAIL) { 1462 /* DBG_871X("802.11w BIP verify fail\n"); */ 1463 goto validate_80211w_fail; 1464 } else if (BIP_ret == RTW_RX_HANDLED) { 1465 /* DBG_871X("802.11w recv none protected packet\n"); */ 1466 /* issue sa query request */ 1467 issue_action_SA_Query(adapter, NULL, 0, 0); 1468 goto validate_80211w_fail; 1469 } 1470 } else { /* 802.11w protect */ 1471 if (subtype == WIFI_ACTION) { 1472 /* according 802.11-2012 standard, these five types are not robust types */ 1473 if (ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_PUBLIC && 1474 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_HT && 1475 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_UNPROTECTED_WNM && 1476 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_SELF_PROTECTED && 1477 ptr[WLAN_HDR_A3_LEN] != RTW_WLAN_CATEGORY_P2P) { 1478 DBG_871X("action frame category =%d should robust\n", ptr[WLAN_HDR_A3_LEN]); 1479 goto validate_80211w_fail; 1480 } 1481 } else if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC) { 1482 DBG_871X("802.11w recv none protected packet\n"); 1483 /* issue sa query request */ 1484 issue_action_SA_Query(adapter, NULL, 0, 0); 1485 goto validate_80211w_fail; 1486 } 1487 } 1488 } 1489 return _SUCCESS; 1490 1491 validate_80211w_fail: 1492 return _FAIL; 1493 1494 } 1495 1496 static inline void dump_rx_packet(u8 *ptr) 1497 { 1498 int i; 1499 1500 DBG_871X("#############################\n"); 1501 for (i = 0; i < 64; i = i+8) 1502 DBG_871X("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr+i), 1503 *(ptr+i+1), *(ptr+i+2), *(ptr+i+3), *(ptr+i+4), *(ptr+i+5), *(ptr+i+6), *(ptr+i+7)); 1504 DBG_871X("#############################\n"); 1505 } 1506 1507 sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame); 1508 sint validate_recv_frame(struct adapter *adapter, union recv_frame *precv_frame) 1509 { 1510 /* shall check frame subtype, to / from ds, da, bssid */ 1511 1512 /* then call check if rx seq/frag. duplicated. */ 1513 1514 u8 type; 1515 u8 subtype; 1516 sint retval = _SUCCESS; 1517 u8 bDumpRxPkt; 1518 1519 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 1520 1521 u8 *ptr = precv_frame->u.hdr.rx_data; 1522 u8 ver = (unsigned char) (*ptr)&0x3; 1523 1524 /* add version chk */ 1525 if (ver != 0) { 1526 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! (ver!= 0)\n")); 1527 retval = _FAIL; 1528 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ver_err); 1529 goto exit; 1530 } 1531 1532 type = GetFrameType(ptr); 1533 subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */ 1534 1535 pattrib->to_fr_ds = get_tofr_ds(ptr); 1536 1537 pattrib->frag_num = GetFragNum(ptr); 1538 pattrib->seq_num = GetSequence(ptr); 1539 1540 pattrib->pw_save = GetPwrMgt(ptr); 1541 pattrib->mfrag = GetMFrag(ptr); 1542 pattrib->mdata = GetMData(ptr); 1543 pattrib->privacy = GetPrivacy(ptr); 1544 pattrib->order = GetOrder(ptr); 1545 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); 1546 if (bDumpRxPkt == 1) /* dump all rx packets */ 1547 dump_rx_packet(ptr); 1548 else if ((bDumpRxPkt == 2) && (type == WIFI_MGT_TYPE)) 1549 dump_rx_packet(ptr); 1550 else if ((bDumpRxPkt == 3) && (type == WIFI_DATA_TYPE)) 1551 dump_rx_packet(ptr); 1552 1553 switch (type) { 1554 case WIFI_MGT_TYPE: /* mgnt */ 1555 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt); 1556 if (validate_80211w_mgmt(adapter, precv_frame) == _FAIL) { 1557 retval = _FAIL; 1558 DBG_COUNTER(padapter->rx_logs.core_rx_pre_mgmt_err_80211w); 1559 break; 1560 } 1561 1562 retval = validate_recv_mgnt_frame(adapter, precv_frame); 1563 if (retval == _FAIL) { 1564 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_mgnt_frame fail\n")); 1565 DBG_COUNTER(adapter->rx_logs.core_rx_pre_mgmt_err); 1566 } 1567 retval = _FAIL; /* only data frame return _SUCCESS */ 1568 break; 1569 case WIFI_CTRL_TYPE: /* ctrl */ 1570 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl); 1571 retval = validate_recv_ctrl_frame(adapter, precv_frame); 1572 if (retval == _FAIL) { 1573 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_ctrl_frame fail\n")); 1574 DBG_COUNTER(adapter->rx_logs.core_rx_pre_ctrl_err); 1575 } 1576 retval = _FAIL; /* only data frame return _SUCCESS */ 1577 break; 1578 case WIFI_DATA_TYPE: /* data */ 1579 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data); 1580 1581 pattrib->qos = (subtype & BIT(7)) ? 1:0; 1582 retval = validate_recv_data_frame(adapter, precv_frame); 1583 if (retval == _FAIL) { 1584 struct recv_priv *precvpriv = &adapter->recvpriv; 1585 /* RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail\n")); */ 1586 precvpriv->rx_drop++; 1587 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_err); 1588 } else if (retval == _SUCCESS) { 1589 #ifdef DBG_RX_DUMP_EAP 1590 u8 bDumpRxPkt; 1591 u16 eth_type; 1592 1593 /* dump eapol */ 1594 rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt)); 1595 /* get ether_type */ 1596 memcpy(ð_type, ptr + pattrib->hdrlen + pattrib->iv_len + LLC_HEADER_SIZE, 2); 1597 eth_type = ntohs((unsigned short) eth_type); 1598 if ((bDumpRxPkt == 4) && (eth_type == 0x888e)) 1599 dump_rx_packet(ptr); 1600 #endif 1601 } else 1602 DBG_COUNTER(adapter->rx_logs.core_rx_pre_data_handled); 1603 break; 1604 default: 1605 DBG_COUNTER(adapter->rx_logs.core_rx_pre_unknown); 1606 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("validate_recv_data_frame fail! type = 0x%x\n", type)); 1607 #ifdef DBG_RX_DROP_FRAME 1608 DBG_871X("DBG_RX_DROP_FRAME validate_recv_data_frame fail! type = 0x%x\n", type); 1609 #endif 1610 retval = _FAIL; 1611 break; 1612 } 1613 1614 exit: 1615 return retval; 1616 } 1617 1618 1619 /* remove the wlanhdr and add the eth_hdr */ 1620 sint wlanhdr_to_ethhdr(union recv_frame *precvframe); 1621 sint wlanhdr_to_ethhdr(union recv_frame *precvframe) 1622 { 1623 sint rmv_len; 1624 u16 eth_type, len; 1625 u8 bsnaphdr; 1626 u8 *psnap_type; 1627 struct ieee80211_snap_hdr *psnap; 1628 __be16 be_tmp; 1629 sint ret = _SUCCESS; 1630 struct adapter *adapter = precvframe->u.hdr.adapter; 1631 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 1632 u8 *ptr = get_recvframe_data(precvframe) ; /* point to frame_ctrl field */ 1633 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; 1634 1635 if (pattrib->encrypt) { 1636 recvframe_pull_tail(precvframe, pattrib->icv_len); 1637 } 1638 1639 psnap = (struct ieee80211_snap_hdr *)(ptr+pattrib->hdrlen + pattrib->iv_len); 1640 psnap_type = ptr+pattrib->hdrlen + pattrib->iv_len+SNAP_SIZE; 1641 /* convert hdr + possible LLC headers into Ethernet header */ 1642 /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */ 1643 if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) && 1644 (memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2)) && 1645 (memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2))) || 1646 /* eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) || */ 1647 !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) { 1648 /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */ 1649 bsnaphdr = true; 1650 } else 1651 /* Leave Ethernet header part of hdr and full payload */ 1652 bsnaphdr = false; 1653 1654 rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr?SNAP_SIZE:0); 1655 len = precvframe->u.hdr.len - rmv_len; 1656 1657 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("\n ===pattrib->hdrlen: %x, pattrib->iv_len:%x ===\n\n", pattrib->hdrlen, pattrib->iv_len)); 1658 1659 memcpy(&be_tmp, ptr+rmv_len, 2); 1660 eth_type = ntohs(be_tmp); /* pattrib->ether_type */ 1661 pattrib->eth_type = eth_type; 1662 1663 #ifdef CONFIG_AUTO_AP_MODE 1664 if (0x8899 == pattrib->eth_type) { 1665 struct sta_info *psta = precvframe->u.hdr.psta; 1666 1667 DBG_871X("wlan rx: got eth_type = 0x%x\n", pattrib->eth_type); 1668 1669 if (psta && psta->isrc && psta->pid > 0) { 1670 u16 rx_pid; 1671 1672 rx_pid = *(u16 *)(ptr+rmv_len+2); 1673 1674 DBG_871X("wlan rx(pid = 0x%x): sta("MAC_FMT") pid = 0x%x\n", 1675 rx_pid, MAC_ARG(psta->hwaddr), psta->pid); 1676 1677 if (rx_pid == psta->pid) { 1678 int i; 1679 u16 len = *(u16 *)(ptr+rmv_len+4); 1680 /* u16 ctrl_type = *(u16*)(ptr+rmv_len+6); */ 1681 1682 /* DBG_871X("RC: len = 0x%x, ctrl_type = 0x%x\n", len, ctrl_type); */ 1683 DBG_871X("RC: len = 0x%x\n", len); 1684 1685 for (i = 0; i < len ; i++) 1686 DBG_871X("0x%x\n", *(ptr+rmv_len+6+i)); 1687 /* DBG_871X("0x%x\n", *(ptr+rmv_len+8+i)); */ 1688 1689 DBG_871X("RC-end\n"); 1690 } 1691 } 1692 } 1693 #endif /* CONFIG_AUTO_AP_MODE */ 1694 1695 if ((check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)) { 1696 ptr += rmv_len; 1697 *ptr = 0x87; 1698 *(ptr+1) = 0x12; 1699 1700 eth_type = 0x8712; 1701 /* append rx status for mp test packets */ 1702 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr)+2)-24); 1703 memcpy(ptr, get_rxmem(precvframe), 24); 1704 ptr += 24; 1705 } else 1706 ptr = recvframe_pull(precvframe, (rmv_len-sizeof(struct ethhdr) + (bsnaphdr?2:0))); 1707 1708 memcpy(ptr, pattrib->dst, ETH_ALEN); 1709 memcpy(ptr+ETH_ALEN, pattrib->src, ETH_ALEN); 1710 1711 if (!bsnaphdr) { 1712 be_tmp = htons(len); 1713 memcpy(ptr+12, &be_tmp, 2); 1714 } 1715 1716 return ret; 1717 } 1718 1719 /* perform defrag */ 1720 static union recv_frame *recvframe_defrag(struct adapter *adapter, 1721 struct __queue *defrag_q) 1722 { 1723 struct list_head *plist, *phead; 1724 u8 *data, wlanhdr_offset; 1725 u8 curfragnum; 1726 struct recv_frame_hdr *pfhdr, *pnfhdr; 1727 union recv_frame *prframe, *pnextrframe; 1728 struct __queue *pfree_recv_queue; 1729 1730 curfragnum = 0; 1731 pfree_recv_queue = &adapter->recvpriv.free_recv_queue; 1732 1733 phead = get_list_head(defrag_q); 1734 plist = get_next(phead); 1735 prframe = LIST_CONTAINOR(plist, union recv_frame, u); 1736 pfhdr = &prframe->u.hdr; 1737 list_del_init(&(prframe->u.list)); 1738 1739 if (curfragnum != pfhdr->attrib.frag_num) { 1740 /* the first fragment number must be 0 */ 1741 /* free the whole queue */ 1742 rtw_free_recvframe(prframe, pfree_recv_queue); 1743 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); 1744 1745 return NULL; 1746 } 1747 1748 curfragnum++; 1749 1750 plist = get_list_head(defrag_q); 1751 1752 plist = get_next(plist); 1753 1754 data = get_recvframe_data(prframe); 1755 1756 while (phead != plist) { 1757 pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u); 1758 pnfhdr = &pnextrframe->u.hdr; 1759 1760 1761 /* check the fragment sequence (2nd ~n fragment frame) */ 1762 1763 if (curfragnum != pnfhdr->attrib.frag_num) { 1764 /* the fragment number must be increasing (after decache) */ 1765 /* release the defrag_q & prframe */ 1766 rtw_free_recvframe(prframe, pfree_recv_queue); 1767 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); 1768 return NULL; 1769 } 1770 1771 curfragnum++; 1772 1773 /* copy the 2nd~n fragment frame's payload to the first fragment */ 1774 /* get the 2nd~last fragment frame's payload */ 1775 1776 wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len; 1777 1778 recvframe_pull(pnextrframe, wlanhdr_offset); 1779 1780 /* append to first fragment frame's tail (if privacy frame, pull the ICV) */ 1781 recvframe_pull_tail(prframe, pfhdr->attrib.icv_len); 1782 1783 /* memcpy */ 1784 memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len); 1785 1786 recvframe_put(prframe, pnfhdr->len); 1787 1788 pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len; 1789 plist = get_next(plist); 1790 1791 }; 1792 1793 /* free the defrag_q queue and return the prframe */ 1794 rtw_free_recvframe_queue(defrag_q, pfree_recv_queue); 1795 1796 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Performance defrag!!!!!\n")); 1797 1798 return prframe; 1799 } 1800 1801 /* check if need to defrag, if needed queue the frame to defrag_q */ 1802 union recv_frame *recvframe_chk_defrag(struct adapter *padapter, union recv_frame *precv_frame) 1803 { 1804 u8 ismfrag; 1805 u8 fragnum; 1806 u8 *psta_addr; 1807 struct recv_frame_hdr *pfhdr; 1808 struct sta_info *psta; 1809 struct sta_priv *pstapriv; 1810 struct list_head *phead; 1811 union recv_frame *prtnframe = NULL; 1812 struct __queue *pfree_recv_queue, *pdefrag_q; 1813 1814 pstapriv = &padapter->stapriv; 1815 1816 pfhdr = &precv_frame->u.hdr; 1817 1818 pfree_recv_queue = &padapter->recvpriv.free_recv_queue; 1819 1820 /* need to define struct of wlan header frame ctrl */ 1821 ismfrag = pfhdr->attrib.mfrag; 1822 fragnum = pfhdr->attrib.frag_num; 1823 1824 psta_addr = pfhdr->attrib.ta; 1825 psta = rtw_get_stainfo(pstapriv, psta_addr); 1826 if (psta == NULL) { 1827 u8 type = GetFrameType(pfhdr->rx_data); 1828 if (type != WIFI_DATA_TYPE) { 1829 psta = rtw_get_bcmc_stainfo(padapter); 1830 pdefrag_q = &psta->sta_recvpriv.defrag_q; 1831 } else 1832 pdefrag_q = NULL; 1833 } else 1834 pdefrag_q = &psta->sta_recvpriv.defrag_q; 1835 1836 if ((ismfrag == 0) && (fragnum == 0)) 1837 prtnframe = precv_frame;/* isn't a fragment frame */ 1838 1839 if (ismfrag == 1) { 1840 /* 0~(n-1) fragment frame */ 1841 /* enqueue to defraf_g */ 1842 if (pdefrag_q != NULL) { 1843 if (fragnum == 0) 1844 /* the first fragment */ 1845 if (!list_empty(&pdefrag_q->queue)) 1846 /* free current defrag_q */ 1847 rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue); 1848 1849 1850 /* Then enqueue the 0~(n-1) fragment into the defrag_q */ 1851 1852 /* spin_lock(&pdefrag_q->lock); */ 1853 phead = get_list_head(pdefrag_q); 1854 list_add_tail(&pfhdr->list, phead); 1855 /* spin_unlock(&pdefrag_q->lock); */ 1856 1857 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("Enqueuq: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum)); 1858 1859 prtnframe = NULL; 1860 1861 } else{ 1862 /* can't find this ta's defrag_queue, so free this recv_frame */ 1863 rtw_free_recvframe(precv_frame, pfree_recv_queue); 1864 prtnframe = NULL; 1865 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum)); 1866 } 1867 1868 } 1869 1870 if ((ismfrag == 0) && (fragnum != 0)) { 1871 /* the last fragment frame */ 1872 /* enqueue the last fragment */ 1873 if (pdefrag_q != NULL) { 1874 /* spin_lock(&pdefrag_q->lock); */ 1875 phead = get_list_head(pdefrag_q); 1876 list_add_tail(&pfhdr->list, phead); 1877 /* spin_unlock(&pdefrag_q->lock); */ 1878 1879 /* call recvframe_defrag to defrag */ 1880 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("defrag: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum)); 1881 precv_frame = recvframe_defrag(padapter, pdefrag_q); 1882 prtnframe = precv_frame; 1883 1884 } else{ 1885 /* can't find this ta's defrag_queue, so free this recv_frame */ 1886 rtw_free_recvframe(precv_frame, pfree_recv_queue); 1887 prtnframe = NULL; 1888 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n", ismfrag, fragnum)); 1889 } 1890 1891 } 1892 1893 1894 if ((prtnframe != NULL) && (prtnframe->u.hdr.attrib.privacy)) { 1895 /* after defrag we must check tkip mic code */ 1896 if (recvframe_chkmic(padapter, prtnframe) == _FAIL) { 1897 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chkmic(padapter, prtnframe) == _FAIL\n")); 1898 rtw_free_recvframe(prtnframe, pfree_recv_queue); 1899 prtnframe = NULL; 1900 } 1901 } 1902 return prtnframe; 1903 } 1904 1905 static int amsdu_to_msdu(struct adapter *padapter, union recv_frame *prframe) 1906 { 1907 int a_len, padding_len; 1908 u16 nSubframe_Length; 1909 u8 nr_subframes, i; 1910 u8 *pdata; 1911 _pkt *sub_pkt, *subframes[MAX_SUBFRAME_COUNT]; 1912 struct recv_priv *precvpriv = &padapter->recvpriv; 1913 struct __queue *pfree_recv_queue = &(precvpriv->free_recv_queue); 1914 int ret = _SUCCESS; 1915 1916 nr_subframes = 0; 1917 1918 recvframe_pull(prframe, prframe->u.hdr.attrib.hdrlen); 1919 1920 if (prframe->u.hdr.attrib.iv_len > 0) 1921 recvframe_pull(prframe, prframe->u.hdr.attrib.iv_len); 1922 1923 a_len = prframe->u.hdr.len; 1924 1925 pdata = prframe->u.hdr.rx_data; 1926 1927 while (a_len > ETH_HLEN) { 1928 1929 /* Offset 12 denote 2 mac address */ 1930 nSubframe_Length = RTW_GET_BE16(pdata + 12); 1931 1932 if (a_len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { 1933 DBG_871X("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length); 1934 break; 1935 } 1936 1937 sub_pkt = rtw_os_alloc_msdu_pkt(prframe, nSubframe_Length, pdata); 1938 if (sub_pkt == NULL) { 1939 DBG_871X("%s(): allocate sub packet fail !!!\n", __func__); 1940 break; 1941 } 1942 1943 /* move the data point to data content */ 1944 pdata += ETH_HLEN; 1945 a_len -= ETH_HLEN; 1946 1947 subframes[nr_subframes++] = sub_pkt; 1948 1949 if (nr_subframes >= MAX_SUBFRAME_COUNT) { 1950 DBG_871X("ParseSubframe(): Too many Subframes! Packets dropped!\n"); 1951 break; 1952 } 1953 1954 pdata += nSubframe_Length; 1955 a_len -= nSubframe_Length; 1956 if (a_len != 0) { 1957 padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4-1)); 1958 if (padding_len == 4) { 1959 padding_len = 0; 1960 } 1961 1962 if (a_len < padding_len) { 1963 DBG_871X("ParseSubframe(): a_len < padding_len !\n"); 1964 break; 1965 } 1966 pdata += padding_len; 1967 a_len -= padding_len; 1968 } 1969 } 1970 1971 for (i = 0; i < nr_subframes; i++) { 1972 sub_pkt = subframes[i]; 1973 1974 /* Indicat the packets to upper layer */ 1975 if (sub_pkt) { 1976 rtw_os_recv_indicate_pkt(padapter, sub_pkt, &prframe->u.hdr.attrib); 1977 } 1978 } 1979 1980 prframe->u.hdr.len = 0; 1981 rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */ 1982 1983 return ret; 1984 } 1985 1986 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num); 1987 int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num) 1988 { 1989 struct adapter *padapter = preorder_ctrl->padapter; 1990 struct dvobj_priv *psdpriv = padapter->dvobj; 1991 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 1992 u8 wsize = preorder_ctrl->wsize_b; 1993 u16 wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/* 4096; */ 1994 1995 /* Rx Reorder initialize condition. */ 1996 if (preorder_ctrl->indicate_seq == 0xFFFF) { 1997 preorder_ctrl->indicate_seq = seq_num; 1998 #ifdef DBG_RX_SEQ 1999 DBG_871X("DBG_RX_SEQ %s:%d init IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2000 preorder_ctrl->indicate_seq, seq_num); 2001 #endif 2002 2003 /* DbgPrint("check_indicate_seq, 1st->indicate_seq =%d\n", precvpriv->indicate_seq); */ 2004 } 2005 2006 /* DbgPrint("enter->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */ 2007 2008 /* Drop out the packet which SeqNum is smaller than WinStart */ 2009 if (SN_LESS(seq_num, preorder_ctrl->indicate_seq)) { 2010 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */ 2011 /* DbgPrint("CheckRxTsIndicateSeq(): Packet Drop! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */ 2012 2013 #ifdef DBG_RX_DROP_FRAME 2014 DBG_871X("%s IndicateSeq: %d > NewSeq: %d\n", __func__, 2015 preorder_ctrl->indicate_seq, seq_num); 2016 #endif 2017 2018 2019 return false; 2020 } 2021 2022 /* */ 2023 /* Sliding window manipulation. Conditions includes: */ 2024 /* 1. Incoming SeqNum is equal to WinStart =>Window shift 1 */ 2025 /* 2. Incoming SeqNum is larger than the WinEnd => Window shift N */ 2026 /* */ 2027 if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) { 2028 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; 2029 2030 #ifdef DBG_RX_SEQ 2031 DBG_871X("DBG_RX_SEQ %s:%d SN_EQUAL IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2032 preorder_ctrl->indicate_seq, seq_num); 2033 #endif 2034 } else if (SN_LESS(wend, seq_num)) { 2035 /* RT_TRACE(COMP_RX_REORDER, DBG_LOUD, ("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, NewSeqNum)); */ 2036 /* DbgPrint("CheckRxTsIndicateSeq(): Window Shift! IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */ 2037 2038 /* boundary situation, when seq_num cross 0xFFF */ 2039 if (seq_num >= (wsize - 1)) 2040 preorder_ctrl->indicate_seq = seq_num + 1 - wsize; 2041 else 2042 preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1; 2043 pdbgpriv->dbg_rx_ampdu_window_shift_cnt++; 2044 #ifdef DBG_RX_SEQ 2045 DBG_871X("DBG_RX_SEQ %s:%d SN_LESS(wend, seq_num) IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2046 preorder_ctrl->indicate_seq, seq_num); 2047 #endif 2048 } 2049 2050 /* DbgPrint("exit->check_indicate_seq(): IndicateSeq: %d, NewSeq: %d\n", precvpriv->indicate_seq, seq_num); */ 2051 2052 return true; 2053 } 2054 2055 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe); 2056 int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, union recv_frame *prframe) 2057 { 2058 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; 2059 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; 2060 struct list_head *phead, *plist; 2061 union recv_frame *pnextrframe; 2062 struct rx_pkt_attrib *pnextattrib; 2063 2064 /* DbgPrint("+enqueue_reorder_recvframe()\n"); */ 2065 2066 /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */ 2067 /* spin_lock(&ppending_recvframe_queue->lock); */ 2068 2069 2070 phead = get_list_head(ppending_recvframe_queue); 2071 plist = get_next(phead); 2072 2073 while (phead != plist) { 2074 pnextrframe = LIST_CONTAINOR(plist, union recv_frame, u); 2075 pnextattrib = &pnextrframe->u.hdr.attrib; 2076 2077 if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) 2078 plist = get_next(plist); 2079 else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) 2080 /* Duplicate entry is found!! Do not insert current entry. */ 2081 /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */ 2082 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */ 2083 return false; 2084 else 2085 break; 2086 2087 /* DbgPrint("enqueue_reorder_recvframe():while\n"); */ 2088 2089 } 2090 2091 2092 /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */ 2093 /* spin_lock(&ppending_recvframe_queue->lock); */ 2094 2095 list_del_init(&(prframe->u.hdr.list)); 2096 2097 list_add_tail(&(prframe->u.hdr.list), plist); 2098 2099 /* spin_unlock(&ppending_recvframe_queue->lock); */ 2100 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */ 2101 2102 2103 /* RT_TRACE(COMP_RX_REORDER, DBG_TRACE, ("InsertRxReorderList(): Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum)); */ 2104 return true; 2105 2106 } 2107 2108 void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq); 2109 void recv_indicatepkts_pkt_loss_cnt(struct debug_priv *pdbgpriv, u64 prev_seq, u64 current_seq) 2110 { 2111 if (current_seq < prev_seq) 2112 pdbgpriv->dbg_rx_ampdu_loss_count += (4096 + current_seq - prev_seq); 2113 else 2114 pdbgpriv->dbg_rx_ampdu_loss_count += (current_seq - prev_seq); 2115 2116 } 2117 int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced); 2118 int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced) 2119 { 2120 struct list_head *phead, *plist; 2121 union recv_frame *prframe; 2122 struct rx_pkt_attrib *pattrib; 2123 /* u8 index = 0; */ 2124 int bPktInBuf = false; 2125 struct recv_priv *precvpriv = &padapter->recvpriv; 2126 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; 2127 struct dvobj_priv *psdpriv = padapter->dvobj; 2128 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 2129 2130 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_in_oder); 2131 2132 /* DbgPrint("+recv_indicatepkts_in_order\n"); */ 2133 2134 /* spin_lock_irqsave(&ppending_recvframe_queue->lock, irql); */ 2135 /* spin_lock(&ppending_recvframe_queue->lock); */ 2136 2137 phead = get_list_head(ppending_recvframe_queue); 2138 plist = get_next(phead); 2139 2140 /* Handling some condition for forced indicate case. */ 2141 if (bforced == true) { 2142 pdbgpriv->dbg_rx_ampdu_forced_indicate_count++; 2143 if (list_empty(phead)) { 2144 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */ 2145 /* spin_unlock(&ppending_recvframe_queue->lock); */ 2146 return true; 2147 } 2148 2149 prframe = LIST_CONTAINOR(plist, union recv_frame, u); 2150 pattrib = &prframe->u.hdr.attrib; 2151 2152 #ifdef DBG_RX_SEQ 2153 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2154 preorder_ctrl->indicate_seq, pattrib->seq_num); 2155 #endif 2156 recv_indicatepkts_pkt_loss_cnt(pdbgpriv, preorder_ctrl->indicate_seq, pattrib->seq_num); 2157 preorder_ctrl->indicate_seq = pattrib->seq_num; 2158 2159 } 2160 2161 /* Prepare indication list and indication. */ 2162 /* Check if there is any packet need indicate. */ 2163 while (!list_empty(phead)) { 2164 2165 prframe = LIST_CONTAINOR(plist, union recv_frame, u); 2166 pattrib = &prframe->u.hdr.attrib; 2167 2168 if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) { 2169 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, 2170 ("recv_indicatepkts_in_order: indicate =%d seq =%d amsdu =%d\n", 2171 preorder_ctrl->indicate_seq, pattrib->seq_num, pattrib->amsdu)); 2172 2173 plist = get_next(plist); 2174 list_del_init(&(prframe->u.hdr.list)); 2175 2176 if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num)) { 2177 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF; 2178 #ifdef DBG_RX_SEQ 2179 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2180 preorder_ctrl->indicate_seq, pattrib->seq_num); 2181 #endif 2182 } 2183 2184 /* Set this as a lock to make sure that only one thread is indicating packet. */ 2185 /* pTS->RxIndicateState = RXTS_INDICATE_PROCESSING; */ 2186 2187 /* Indicate packets */ 2188 /* RT_ASSERT((index<=REORDER_WIN_SIZE), ("RxReorderIndicatePacket(): Rx Reorder buffer full!!\n")); */ 2189 2190 2191 /* indicate this recv_frame */ 2192 /* DbgPrint("recv_indicatepkts_in_order, indicate_seq =%d, seq_num =%d\n", precvpriv->indicate_seq, pattrib->seq_num); */ 2193 if (!pattrib->amsdu) { 2194 /* DBG_871X("recv_indicatepkts_in_order, amsdu!= 1, indicate_seq =%d, seq_num =%d\n", preorder_ctrl->indicate_seq, pattrib->seq_num); */ 2195 2196 if ((padapter->bDriverStopped == false) && 2197 (padapter->bSurpriseRemoved == false)) 2198 rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */ 2199 2200 } else if (pattrib->amsdu == 1) { 2201 if (amsdu_to_msdu(padapter, prframe) != _SUCCESS) 2202 rtw_free_recvframe(prframe, &precvpriv->free_recv_queue); 2203 2204 } else{ 2205 /* error condition; */ 2206 } 2207 2208 2209 /* Update local variables. */ 2210 bPktInBuf = false; 2211 2212 } else{ 2213 bPktInBuf = true; 2214 break; 2215 } 2216 2217 /* DbgPrint("recv_indicatepkts_in_order():while\n"); */ 2218 2219 } 2220 2221 /* spin_unlock(&ppending_recvframe_queue->lock); */ 2222 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */ 2223 2224 return bPktInBuf; 2225 } 2226 2227 int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *prframe); 2228 int recv_indicatepkt_reorder(struct adapter *padapter, union recv_frame *prframe) 2229 { 2230 int retval = _SUCCESS; 2231 struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; 2232 struct recv_reorder_ctrl *preorder_ctrl = prframe->u.hdr.preorder_ctrl; 2233 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; 2234 struct dvobj_priv *psdpriv = padapter->dvobj; 2235 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg; 2236 2237 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_reoder); 2238 2239 if (!pattrib->amsdu) { 2240 /* s1. */ 2241 wlanhdr_to_ethhdr(prframe); 2242 2243 if (pattrib->qos != 1) { 2244 if ((padapter->bDriverStopped == false) && 2245 (padapter->bSurpriseRemoved == false)) { 2246 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ recv_indicatepkt_reorder -recv_func recv_indicatepkt\n")); 2247 2248 rtw_recv_indicatepkt(padapter, prframe); 2249 return _SUCCESS; 2250 2251 } 2252 2253 #ifdef DBG_RX_DROP_FRAME 2254 DBG_871X("DBG_RX_DROP_FRAME %s pattrib->qos != 1\n", __func__); 2255 #endif 2256 2257 return _FAIL; 2258 2259 } 2260 2261 if (preorder_ctrl->enable == false) { 2262 /* indicate this recv_frame */ 2263 preorder_ctrl->indicate_seq = pattrib->seq_num; 2264 #ifdef DBG_RX_SEQ 2265 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2266 preorder_ctrl->indicate_seq, pattrib->seq_num); 2267 #endif 2268 2269 rtw_recv_indicatepkt(padapter, prframe); 2270 2271 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; 2272 #ifdef DBG_RX_SEQ 2273 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2274 preorder_ctrl->indicate_seq, pattrib->seq_num); 2275 #endif 2276 2277 return _SUCCESS; 2278 } 2279 } else if (pattrib->amsdu == 1) { /* temp filter -> means didn't support A-MSDUs in a A-MPDU */ 2280 if (preorder_ctrl->enable == false) { 2281 preorder_ctrl->indicate_seq = pattrib->seq_num; 2282 #ifdef DBG_RX_SEQ 2283 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2284 preorder_ctrl->indicate_seq, pattrib->seq_num); 2285 #endif 2286 2287 retval = amsdu_to_msdu(padapter, prframe); 2288 2289 preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1)%4096; 2290 #ifdef DBG_RX_SEQ 2291 DBG_871X("DBG_RX_SEQ %s:%d IndicateSeq: %d, NewSeq: %d\n", __func__, __LINE__, 2292 preorder_ctrl->indicate_seq, pattrib->seq_num); 2293 #endif 2294 2295 if (retval != _SUCCESS) { 2296 #ifdef DBG_RX_DROP_FRAME 2297 DBG_871X("DBG_RX_DROP_FRAME %s amsdu_to_msdu fail\n", __func__); 2298 #endif 2299 } 2300 2301 return retval; 2302 } 2303 } 2304 2305 spin_lock_bh(&ppending_recvframe_queue->lock); 2306 2307 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, 2308 ("recv_indicatepkt_reorder: indicate =%d seq =%d\n", 2309 preorder_ctrl->indicate_seq, pattrib->seq_num)); 2310 2311 /* s2. check if winstart_b(indicate_seq) needs to been updated */ 2312 if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) { 2313 pdbgpriv->dbg_rx_ampdu_drop_count++; 2314 #ifdef DBG_RX_DROP_FRAME 2315 DBG_871X("DBG_RX_DROP_FRAME %s check_indicate_seq fail\n", __func__); 2316 #endif 2317 goto _err_exit; 2318 } 2319 2320 2321 /* s3. Insert all packet into Reorder Queue to maintain its ordering. */ 2322 if (!enqueue_reorder_recvframe(preorder_ctrl, prframe)) { 2323 /* DbgPrint("recv_indicatepkt_reorder, enqueue_reorder_recvframe fail!\n"); */ 2324 /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock, irql); */ 2325 /* return _FAIL; */ 2326 #ifdef DBG_RX_DROP_FRAME 2327 DBG_871X("DBG_RX_DROP_FRAME %s enqueue_reorder_recvframe fail\n", __func__); 2328 #endif 2329 goto _err_exit; 2330 } 2331 2332 2333 /* s4. */ 2334 /* Indication process. */ 2335 /* After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */ 2336 /* with the SeqNum smaller than latest WinStart and buffer other packets. */ 2337 /* */ 2338 /* For Rx Reorder condition: */ 2339 /* 1. All packets with SeqNum smaller than WinStart => Indicate */ 2340 /* 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */ 2341 /* */ 2342 2343 /* recv_indicatepkts_in_order(padapter, preorder_ctrl, true); */ 2344 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) { 2345 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); 2346 spin_unlock_bh(&ppending_recvframe_queue->lock); 2347 } else{ 2348 spin_unlock_bh(&ppending_recvframe_queue->lock); 2349 del_timer_sync(&preorder_ctrl->reordering_ctrl_timer); 2350 } 2351 2352 return _SUCCESS; 2353 2354 _err_exit: 2355 spin_unlock_bh(&ppending_recvframe_queue->lock); 2356 2357 return _FAIL; 2358 } 2359 2360 2361 void rtw_reordering_ctrl_timeout_handler(void *pcontext) 2362 { 2363 struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext; 2364 struct adapter *padapter = preorder_ctrl->padapter; 2365 struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue; 2366 2367 2368 if (padapter->bDriverStopped || padapter->bSurpriseRemoved) 2369 return; 2370 2371 /* DBG_871X("+rtw_reordering_ctrl_timeout_handler() =>\n"); */ 2372 2373 spin_lock_bh(&ppending_recvframe_queue->lock); 2374 2375 if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true) 2376 _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME); 2377 2378 spin_unlock_bh(&ppending_recvframe_queue->lock); 2379 2380 } 2381 2382 int process_recv_indicatepkts(struct adapter *padapter, union recv_frame *prframe); 2383 int process_recv_indicatepkts(struct adapter *padapter, union recv_frame *prframe) 2384 { 2385 int retval = _SUCCESS; 2386 /* struct recv_priv *precvpriv = &padapter->recvpriv; */ 2387 /* struct rx_pkt_attrib *pattrib = &prframe->u.hdr.attrib; */ 2388 struct mlme_priv *pmlmepriv = &padapter->mlmepriv; 2389 struct ht_priv *phtpriv = &pmlmepriv->htpriv; 2390 2391 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate); 2392 2393 if (phtpriv->ht_option == true) { /* B/G/N Mode */ 2394 /* prframe->u.hdr.preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */ 2395 2396 if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) { /* including perform A-MPDU Rx Ordering Buffer Control */ 2397 #ifdef DBG_RX_DROP_FRAME 2398 DBG_871X("DBG_RX_DROP_FRAME %s recv_indicatepkt_reorder error!\n", __func__); 2399 #endif 2400 2401 if ((padapter->bDriverStopped == false) && 2402 (padapter->bSurpriseRemoved == false)) { 2403 retval = _FAIL; 2404 return retval; 2405 } 2406 } 2407 } else { /* B/G mode */ 2408 retval = wlanhdr_to_ethhdr(prframe); 2409 if (retval != _SUCCESS) { 2410 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("wlanhdr_to_ethhdr: drop pkt\n")); 2411 #ifdef DBG_RX_DROP_FRAME 2412 DBG_871X("DBG_RX_DROP_FRAME %s wlanhdr_to_ethhdr error!\n", __func__); 2413 #endif 2414 return retval; 2415 } 2416 2417 if ((padapter->bDriverStopped == false) && (padapter->bSurpriseRemoved == false)) { 2418 /* indicate this recv_frame */ 2419 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n")); 2420 rtw_recv_indicatepkt(padapter, prframe); 2421 2422 2423 } else{ 2424 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n")); 2425 2426 RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_, ("recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)", padapter->bDriverStopped, padapter->bSurpriseRemoved)); 2427 retval = _FAIL; 2428 return retval; 2429 } 2430 2431 } 2432 2433 return retval; 2434 2435 } 2436 2437 static int recv_func_prehandle(struct adapter *padapter, union recv_frame *rframe) 2438 { 2439 int ret = _SUCCESS; 2440 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; 2441 2442 DBG_COUNTER(padapter->rx_logs.core_rx_pre); 2443 2444 /* check the frame crtl field and decache */ 2445 ret = validate_recv_frame(padapter, rframe); 2446 if (ret != _SUCCESS) { 2447 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("recv_func: validate_recv_frame fail! drop pkt\n")); 2448 rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */ 2449 goto exit; 2450 } 2451 2452 exit: 2453 return ret; 2454 } 2455 2456 static int recv_func_posthandle(struct adapter *padapter, union recv_frame *prframe) 2457 { 2458 int ret = _SUCCESS; 2459 union recv_frame *orig_prframe = prframe; 2460 struct recv_priv *precvpriv = &padapter->recvpriv; 2461 struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue; 2462 2463 DBG_COUNTER(padapter->rx_logs.core_rx_post); 2464 2465 prframe = decryptor(padapter, prframe); 2466 if (prframe == NULL) { 2467 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("decryptor: drop pkt\n")); 2468 #ifdef DBG_RX_DROP_FRAME 2469 DBG_871X("DBG_RX_DROP_FRAME %s decryptor: drop pkt\n", __func__); 2470 #endif 2471 ret = _FAIL; 2472 DBG_COUNTER(padapter->rx_logs.core_rx_post_decrypt_err); 2473 goto _recv_data_drop; 2474 } 2475 2476 prframe = recvframe_chk_defrag(padapter, prframe); 2477 if (prframe == NULL) { 2478 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recvframe_chk_defrag: drop pkt\n")); 2479 #ifdef DBG_RX_DROP_FRAME 2480 DBG_871X("DBG_RX_DROP_FRAME %s recvframe_chk_defrag: drop pkt\n", __func__); 2481 #endif 2482 DBG_COUNTER(padapter->rx_logs.core_rx_post_defrag_err); 2483 goto _recv_data_drop; 2484 } 2485 2486 prframe = portctrl(padapter, prframe); 2487 if (prframe == NULL) { 2488 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("portctrl: drop pkt\n")); 2489 #ifdef DBG_RX_DROP_FRAME 2490 DBG_871X("DBG_RX_DROP_FRAME %s portctrl: drop pkt\n", __func__); 2491 #endif 2492 ret = _FAIL; 2493 DBG_COUNTER(padapter->rx_logs.core_rx_post_portctrl_err); 2494 goto _recv_data_drop; 2495 } 2496 2497 count_rx_stats(padapter, prframe, NULL); 2498 2499 ret = process_recv_indicatepkts(padapter, prframe); 2500 if (ret != _SUCCESS) { 2501 RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("recv_func: process_recv_indicatepkts fail!\n")); 2502 #ifdef DBG_RX_DROP_FRAME 2503 DBG_871X("DBG_RX_DROP_FRAME %s process_recv_indicatepkts fail!\n", __func__); 2504 #endif 2505 rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */ 2506 DBG_COUNTER(padapter->rx_logs.core_rx_post_indicate_err); 2507 goto _recv_data_drop; 2508 } 2509 2510 _recv_data_drop: 2511 precvpriv->rx_drop++; 2512 return ret; 2513 } 2514 2515 2516 int recv_func(struct adapter *padapter, union recv_frame *rframe); 2517 int recv_func(struct adapter *padapter, union recv_frame *rframe) 2518 { 2519 int ret; 2520 struct rx_pkt_attrib *prxattrib = &rframe->u.hdr.attrib; 2521 struct recv_priv *recvpriv = &padapter->recvpriv; 2522 struct security_priv *psecuritypriv = &padapter->securitypriv; 2523 struct mlme_priv *mlmepriv = &padapter->mlmepriv; 2524 2525 /* check if need to handle uc_swdec_pending_queue*/ 2526 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && psecuritypriv->busetkipkey) { 2527 union recv_frame *pending_frame; 2528 int cnt = 0; 2529 2530 while ((pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue))) { 2531 cnt++; 2532 DBG_COUNTER(padapter->rx_logs.core_rx_dequeue); 2533 recv_func_posthandle(padapter, pending_frame); 2534 } 2535 2536 if (cnt) 2537 DBG_871X(FUNC_ADPT_FMT" dequeue %d from uc_swdec_pending_queue\n", 2538 FUNC_ADPT_ARG(padapter), cnt); 2539 } 2540 2541 DBG_COUNTER(padapter->rx_logs.core_rx); 2542 ret = recv_func_prehandle(padapter, rframe); 2543 2544 if (ret == _SUCCESS) { 2545 2546 /* check if need to enqueue into uc_swdec_pending_queue*/ 2547 if (check_fwstate(mlmepriv, WIFI_STATION_STATE) && 2548 !IS_MCAST(prxattrib->ra) && prxattrib->encrypt > 0 && 2549 (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt == true) && 2550 psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK && 2551 !psecuritypriv->busetkipkey) { 2552 DBG_COUNTER(padapter->rx_logs.core_rx_enqueue); 2553 rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue); 2554 /* DBG_871X("%s: no key, enqueue uc_swdec_pending_queue\n", __func__); */ 2555 2556 if (recvpriv->free_recvframe_cnt < NR_RECVFRAME/4) { 2557 /* to prevent from recvframe starvation, get recvframe from uc_swdec_pending_queue to free_recvframe_cnt */ 2558 rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue); 2559 if (rframe) 2560 goto do_posthandle; 2561 } 2562 goto exit; 2563 } 2564 2565 do_posthandle: 2566 ret = recv_func_posthandle(padapter, rframe); 2567 } 2568 2569 exit: 2570 return ret; 2571 } 2572 2573 2574 s32 rtw_recv_entry(union recv_frame *precvframe) 2575 { 2576 struct adapter *padapter; 2577 struct recv_priv *precvpriv; 2578 s32 ret = _SUCCESS; 2579 2580 /* RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("+rtw_recv_entry\n")); */ 2581 2582 padapter = precvframe->u.hdr.adapter; 2583 2584 precvpriv = &padapter->recvpriv; 2585 2586 ret = recv_func(padapter, precvframe); 2587 if (ret == _FAIL) { 2588 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("rtw_recv_entry: recv_func return fail!!!\n")); 2589 goto _recv_entry_drop; 2590 } 2591 2592 2593 precvpriv->rx_pkts++; 2594 2595 return ret; 2596 2597 _recv_entry_drop: 2598 2599 /* RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, ("_recv_entry_drop\n")); */ 2600 2601 return ret; 2602 } 2603 2604 void rtw_signal_stat_timer_hdl(RTW_TIMER_HDL_ARGS) 2605 { 2606 struct adapter *adapter = (struct adapter *)FunctionContext; 2607 struct recv_priv *recvpriv = &adapter->recvpriv; 2608 2609 u32 tmp_s, tmp_q; 2610 u8 avg_signal_strength = 0; 2611 u8 avg_signal_qual = 0; 2612 u32 num_signal_strength = 0; 2613 u32 num_signal_qual = 0; 2614 u8 _alpha = 5; /* this value is based on converging_constant = 5000 and sampling_interval = 1000 */ 2615 2616 if (adapter->recvpriv.is_signal_dbg) { 2617 /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */ 2618 adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg; 2619 adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg); 2620 } else { 2621 2622 if (recvpriv->signal_strength_data.update_req == 0) {/* update_req is clear, means we got rx */ 2623 avg_signal_strength = recvpriv->signal_strength_data.avg_val; 2624 num_signal_strength = recvpriv->signal_strength_data.total_num; 2625 /* after avg_vals are accquired, we can re-stat the signal values */ 2626 recvpriv->signal_strength_data.update_req = 1; 2627 } 2628 2629 if (recvpriv->signal_qual_data.update_req == 0) {/* update_req is clear, means we got rx */ 2630 avg_signal_qual = recvpriv->signal_qual_data.avg_val; 2631 num_signal_qual = recvpriv->signal_qual_data.total_num; 2632 /* after avg_vals are accquired, we can re-stat the signal values */ 2633 recvpriv->signal_qual_data.update_req = 1; 2634 } 2635 2636 if (num_signal_strength == 0) { 2637 if (rtw_get_on_cur_ch_time(adapter) == 0 2638 || jiffies_to_msecs(jiffies - rtw_get_on_cur_ch_time(adapter)) < 2 * adapter->mlmeextpriv.mlmext_info.bcn_interval 2639 ) { 2640 goto set_timer; 2641 } 2642 } 2643 2644 if (check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY) == true 2645 || check_fwstate(&adapter->mlmepriv, _FW_LINKED) == false 2646 ) { 2647 goto set_timer; 2648 } 2649 2650 /* update value of signal_strength, rssi, signal_qual */ 2651 tmp_s = (avg_signal_strength+(_alpha-1)*recvpriv->signal_strength); 2652 if (tmp_s % _alpha) 2653 tmp_s = tmp_s/_alpha + 1; 2654 else 2655 tmp_s = tmp_s/_alpha; 2656 if (tmp_s > 100) 2657 tmp_s = 100; 2658 2659 tmp_q = (avg_signal_qual+(_alpha-1)*recvpriv->signal_qual); 2660 if (tmp_q % _alpha) 2661 tmp_q = tmp_q/_alpha + 1; 2662 else 2663 tmp_q = tmp_q/_alpha; 2664 if (tmp_q > 100) 2665 tmp_q = 100; 2666 2667 recvpriv->signal_strength = tmp_s; 2668 recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s); 2669 recvpriv->signal_qual = tmp_q; 2670 2671 #if defined(DBG_RX_SIGNAL_DISPLAY_PROCESSING) && 1 2672 DBG_871X(FUNC_ADPT_FMT" signal_strength:%3u, rssi:%3d, signal_qual:%3u" 2673 ", num_signal_strength:%u, num_signal_qual:%u" 2674 ", on_cur_ch_ms:%d" 2675 "\n" 2676 , FUNC_ADPT_ARG(adapter) 2677 , recvpriv->signal_strength 2678 , recvpriv->rssi 2679 , recvpriv->signal_qual 2680 , num_signal_strength, num_signal_qual 2681 , rtw_get_on_cur_ch_time(adapter) ? jiffies_to_msecs(jiffies - rtw_get_on_cur_ch_time(adapter)) : 0 2682 ); 2683 #endif 2684 } 2685 2686 set_timer: 2687 rtw_set_signal_stat_timer(recvpriv); 2688 2689 } 2690