1 // SPDX-License-Identifier: GPL-2.0 2 /****************************************************************************** 3 * rtl871x_recv.c 4 * 5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. 6 * Linux device driver for RTL8192SU 7 * 8 * Modifications for inclusion into the Linux staging tree are 9 * Copyright(c) 2010 Larry Finger. All rights reserved. 10 * 11 * Contact information: 12 * WLAN FAE <wlanfae@realtek.com> 13 * Larry Finger <Larry.Finger@lwfinger.net> 14 * 15 ******************************************************************************/ 16 17 #define _RTL871X_RECV_C_ 18 19 #include <linux/ip.h> 20 #include <linux/slab.h> 21 #include <linux/if_ether.h> 22 #include <linux/kmemleak.h> 23 #include <linux/etherdevice.h> 24 25 #include "osdep_service.h" 26 #include "drv_types.h" 27 #include "recv_osdep.h" 28 #include "mlme_osdep.h" 29 #include "ethernet.h" 30 #include "usb_ops.h" 31 #include "wifi.h" 32 33 static const u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37}; 34 35 /* Datagram Delivery Protocol */ 36 static const u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3}; 37 38 /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ 39 static const u8 bridge_tunnel_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8}; 40 41 /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ 42 static const u8 rfc1042_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; 43 44 void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv) 45 { 46 memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv)); 47 spin_lock_init(&psta_recvpriv->lock); 48 _init_queue(&psta_recvpriv->defrag_q); 49 } 50 51 sint _r8712_init_recv_priv(struct recv_priv *precvpriv, 52 struct _adapter *padapter) 53 { 54 sint i; 55 union recv_frame *precvframe; 56 57 memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv)); 58 spin_lock_init(&precvpriv->lock); 59 _init_queue(&precvpriv->free_recv_queue); 60 _init_queue(&precvpriv->recv_pending_queue); 61 precvpriv->adapter = padapter; 62 precvpriv->free_recvframe_cnt = NR_RECVFRAME; 63 precvpriv->pallocated_frame_buf = kzalloc(NR_RECVFRAME * 64 sizeof(union recv_frame) + RXFRAME_ALIGN_SZ, 65 GFP_ATOMIC); 66 if (precvpriv->pallocated_frame_buf == NULL) 67 return _FAIL; 68 kmemleak_not_leak(precvpriv->pallocated_frame_buf); 69 precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf + 70 RXFRAME_ALIGN_SZ - 71 ((addr_t)(precvpriv->pallocated_frame_buf) & 72 (RXFRAME_ALIGN_SZ - 1)); 73 precvframe = (union recv_frame *)precvpriv->precv_frame_buf; 74 for (i = 0; i < NR_RECVFRAME; i++) { 75 INIT_LIST_HEAD(&(precvframe->u.list)); 76 list_add_tail(&(precvframe->u.list), 77 &(precvpriv->free_recv_queue.queue)); 78 r8712_os_recv_resource_alloc(padapter, precvframe); 79 precvframe->u.hdr.adapter = padapter; 80 precvframe++; 81 } 82 precvpriv->rx_pending_cnt = 1; 83 return r8712_init_recv_priv(precvpriv, padapter); 84 } 85 86 void _r8712_free_recv_priv(struct recv_priv *precvpriv) 87 { 88 kfree(precvpriv->pallocated_frame_buf); 89 r8712_free_recv_priv(precvpriv); 90 } 91 92 union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue) 93 { 94 unsigned long irqL; 95 union recv_frame *precvframe; 96 struct _adapter *padapter; 97 struct recv_priv *precvpriv; 98 99 spin_lock_irqsave(&pfree_recv_queue->lock, irqL); 100 precvframe = list_first_entry_or_null(&pfree_recv_queue->queue, 101 union recv_frame, u.hdr.list); 102 if (precvframe) { 103 list_del_init(&precvframe->u.hdr.list); 104 padapter = precvframe->u.hdr.adapter; 105 if (padapter != NULL) { 106 precvpriv = &padapter->recvpriv; 107 if (pfree_recv_queue == &precvpriv->free_recv_queue) 108 precvpriv->free_recvframe_cnt--; 109 } 110 } 111 spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL); 112 return precvframe; 113 } 114 115 /* 116 * caller : defrag; recvframe_chk_defrag in recv_thread (passive) 117 * pframequeue: defrag_queue : will be accessed in recv_thread (passive) 118 * using spin_lock to protect 119 */ 120 void r8712_free_recvframe_queue(struct __queue *pframequeue, 121 struct __queue *pfree_recv_queue) 122 { 123 union recv_frame *precvframe; 124 struct list_head *plist, *phead; 125 126 spin_lock(&pframequeue->lock); 127 phead = &pframequeue->queue; 128 plist = phead->next; 129 while (!end_of_queue_search(phead, plist)) { 130 precvframe = container_of(plist, union recv_frame, u.list); 131 plist = plist->next; 132 r8712_free_recvframe(precvframe, pfree_recv_queue); 133 } 134 spin_unlock(&pframequeue->lock); 135 } 136 137 sint r8712_recvframe_chkmic(struct _adapter *adapter, 138 union recv_frame *precvframe) 139 { 140 sint i, res = _SUCCESS; 141 u32 datalen; 142 u8 miccode[8]; 143 u8 bmic_err = false; 144 u8 *pframe, *payload, *pframemic; 145 u8 *mickey, idx, *iv; 146 struct sta_info *stainfo; 147 struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib; 148 struct security_priv *psecuritypriv = &adapter->securitypriv; 149 150 stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]); 151 if (prxattrib->encrypt == _TKIP_) { 152 /* calculate mic code */ 153 if (stainfo != NULL) { 154 if (IS_MCAST(prxattrib->ra)) { 155 iv = precvframe->u.hdr.rx_data + 156 prxattrib->hdrlen; 157 idx = iv[3]; 158 mickey = &psecuritypriv->XGrprxmickey[(((idx >> 159 6) & 0x3)) - 1].skey[0]; 160 if (!psecuritypriv->binstallGrpkey) 161 return _FAIL; 162 } else { 163 mickey = &stainfo->tkiprxmickey.skey[0]; 164 } 165 /*icv_len included the mic code*/ 166 datalen = precvframe->u.hdr.len - prxattrib->hdrlen - 167 prxattrib->iv_len - prxattrib->icv_len - 8; 168 pframe = precvframe->u.hdr.rx_data; 169 payload = pframe + prxattrib->hdrlen + 170 prxattrib->iv_len; 171 seccalctkipmic(mickey, pframe, payload, datalen, 172 &miccode[0], 173 (unsigned char)prxattrib->priority); 174 pframemic = payload + datalen; 175 bmic_err = false; 176 for (i = 0; i < 8; i++) { 177 if (miccode[i] != *(pframemic + i)) 178 bmic_err = true; 179 } 180 if (bmic_err) { 181 if (prxattrib->bdecrypted) 182 r8712_handle_tkip_mic_err(adapter, 183 (u8)IS_MCAST(prxattrib->ra)); 184 res = _FAIL; 185 } else { 186 /* mic checked ok */ 187 if (!psecuritypriv->bcheck_grpkey && 188 IS_MCAST(prxattrib->ra)) 189 psecuritypriv->bcheck_grpkey = true; 190 } 191 recvframe_pull_tail(precvframe, 8); 192 } 193 } 194 return res; 195 } 196 197 /* decrypt and set the ivlen,icvlen of the recv_frame */ 198 union recv_frame *r8712_decryptor(struct _adapter *padapter, 199 union recv_frame *precv_frame) 200 { 201 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib; 202 struct security_priv *psecuritypriv = &padapter->securitypriv; 203 union recv_frame *return_packet = precv_frame; 204 205 if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || 206 psecuritypriv->sw_decrypt)) { 207 psecuritypriv->hw_decrypted = false; 208 switch (prxattrib->encrypt) { 209 case _WEP40_: 210 case _WEP104_: 211 r8712_wep_decrypt(padapter, (u8 *)precv_frame); 212 break; 213 case _TKIP_: 214 r8712_tkip_decrypt(padapter, (u8 *)precv_frame); 215 break; 216 case _AES_: 217 r8712_aes_decrypt(padapter, (u8 *)precv_frame); 218 break; 219 default: 220 break; 221 } 222 } else if (prxattrib->bdecrypted == 1) { 223 psecuritypriv->hw_decrypted = true; 224 } 225 return return_packet; 226 } 227 /*###set the security information in the recv_frame */ 228 union recv_frame *r8712_portctrl(struct _adapter *adapter, 229 union recv_frame *precv_frame) 230 { 231 u8 *psta_addr, *ptr; 232 uint auth_alg; 233 struct recv_frame_hdr *pfhdr; 234 struct sta_info *psta; 235 struct sta_priv *pstapriv; 236 union recv_frame *prtnframe; 237 u16 ether_type; 238 239 pstapriv = &adapter->stapriv; 240 ptr = get_recvframe_data(precv_frame); 241 pfhdr = &precv_frame->u.hdr; 242 psta_addr = pfhdr->attrib.ta; 243 psta = r8712_get_stainfo(pstapriv, psta_addr); 244 auth_alg = adapter->securitypriv.AuthAlgrthm; 245 if (auth_alg == 2) { 246 /* get ether_type */ 247 ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE; 248 memcpy(ðer_type, ptr, 2); 249 be16_to_cpus(ðer_type); 250 251 if ((psta != NULL) && (psta->ieee8021x_blocked)) { 252 /* blocked 253 * only accept EAPOL frame 254 */ 255 if (ether_type == 0x888e) { 256 prtnframe = precv_frame; 257 } else { 258 /*free this frame*/ 259 r8712_free_recvframe(precv_frame, 260 &adapter->recvpriv.free_recv_queue); 261 prtnframe = NULL; 262 } 263 } else { 264 /* allowed 265 * check decryption status, and decrypt the 266 * frame if needed 267 */ 268 prtnframe = precv_frame; 269 /* check is the EAPOL frame or not (Rekey) */ 270 if (ether_type == 0x888e) { 271 /* check Rekey */ 272 prtnframe = precv_frame; 273 } 274 } 275 } else { 276 prtnframe = precv_frame; 277 } 278 return prtnframe; 279 } 280 281 static sint recv_decache(union recv_frame *precv_frame, u8 bretry, 282 struct stainfo_rxcache *prxcache) 283 { 284 sint tid = precv_frame->u.hdr.attrib.priority; 285 u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) | 286 (precv_frame->u.hdr.attrib.frag_num & 0xf); 287 288 if (tid > 15) 289 return _FAIL; 290 if (seq_ctrl == prxcache->tid_rxseq[tid]) 291 return _FAIL; 292 prxcache->tid_rxseq[tid] = seq_ctrl; 293 return _SUCCESS; 294 } 295 296 static sint sta2sta_data_frame(struct _adapter *adapter, 297 union recv_frame *precv_frame, 298 struct sta_info **psta) 299 { 300 u8 *ptr = precv_frame->u.hdr.rx_data; 301 sint ret = _SUCCESS; 302 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 303 struct sta_priv *pstapriv = &adapter->stapriv; 304 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 305 u8 *mybssid = get_bssid(pmlmepriv); 306 u8 *myhwaddr = myid(&adapter->eeprompriv); 307 u8 *sta_addr = NULL; 308 sint bmcast = IS_MCAST(pattrib->dst); 309 310 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) || 311 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) { 312 /* filter packets that SA is myself or multicast or broadcast */ 313 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) 314 return _FAIL; 315 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) 316 return _FAIL; 317 if (is_zero_ether_addr(pattrib->bssid) || 318 is_zero_ether_addr(mybssid) || 319 (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) 320 return _FAIL; 321 sta_addr = pattrib->src; 322 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) { 323 /* For Station mode, sa and bssid should always be BSSID, 324 * and DA is my mac-address 325 */ 326 if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) 327 return _FAIL; 328 sta_addr = pattrib->bssid; 329 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 330 if (bmcast) { 331 /* For AP mode, if DA == MCAST, then BSSID should 332 * be also MCAST 333 */ 334 if (!IS_MCAST(pattrib->bssid)) 335 return _FAIL; 336 } else { /* not mc-frame */ 337 /* For AP mode, if DA is non-MCAST, then it must be 338 * BSSID, and bssid == BSSID 339 */ 340 if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) 341 return _FAIL; 342 sta_addr = pattrib->src; 343 } 344 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { 345 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); 346 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); 347 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); 348 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); 349 memcpy(pattrib->ta, pattrib->src, ETH_ALEN); 350 sta_addr = mybssid; 351 } else { 352 ret = _FAIL; 353 } 354 if (bmcast) 355 *psta = r8712_get_bcmc_stainfo(adapter); 356 else 357 *psta = r8712_get_stainfo(pstapriv, sta_addr); /* get ap_info */ 358 if (*psta == NULL) { 359 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) 360 adapter->mppriv.rx_pktloss++; 361 return _FAIL; 362 } 363 return ret; 364 } 365 366 static sint ap2sta_data_frame(struct _adapter *adapter, 367 union recv_frame *precv_frame, 368 struct sta_info **psta) 369 { 370 u8 *ptr = precv_frame->u.hdr.rx_data; 371 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 372 struct sta_priv *pstapriv = &adapter->stapriv; 373 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 374 u8 *mybssid = get_bssid(pmlmepriv); 375 u8 *myhwaddr = myid(&adapter->eeprompriv); 376 sint bmcast = IS_MCAST(pattrib->dst); 377 378 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && 379 check_fwstate(pmlmepriv, _FW_LINKED)) { 380 /* if NULL-frame, drop packet */ 381 if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL) 382 return _FAIL; 383 /* drop QoS-SubType Data, including QoS NULL, 384 * excluding QoS-Data 385 */ 386 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == 387 WIFI_QOS_DATA_TYPE) { 388 if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6))) 389 return _FAIL; 390 } 391 392 /* filter packets that SA is myself or multicast or broadcast */ 393 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) 394 return _FAIL; 395 396 /* da should be for me */ 397 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) 398 return _FAIL; 399 /* check BSSID */ 400 if (is_zero_ether_addr(pattrib->bssid) || 401 is_zero_ether_addr(mybssid) || 402 (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) 403 return _FAIL; 404 if (bmcast) 405 *psta = r8712_get_bcmc_stainfo(adapter); 406 else 407 *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); 408 if (*psta == NULL) 409 return _FAIL; 410 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) && 411 check_fwstate(pmlmepriv, _FW_LINKED)) { 412 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN); 413 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN); 414 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN); 415 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN); 416 memcpy(pattrib->ta, pattrib->src, ETH_ALEN); 417 memcpy(pattrib->bssid, mybssid, ETH_ALEN); 418 *psta = r8712_get_stainfo(pstapriv, pattrib->bssid); 419 if (*psta == NULL) 420 return _FAIL; 421 } else { 422 return _FAIL; 423 } 424 return _SUCCESS; 425 } 426 427 static sint sta2ap_data_frame(struct _adapter *adapter, 428 union recv_frame *precv_frame, 429 struct sta_info **psta) 430 { 431 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 432 struct sta_priv *pstapriv = &adapter->stapriv; 433 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 434 unsigned char *mybssid = get_bssid(pmlmepriv); 435 436 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) { 437 /* For AP mode, if DA is non-MCAST, then it must be BSSID, 438 * and bssid == BSSID 439 * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR 440 */ 441 if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) 442 return _FAIL; 443 *psta = r8712_get_stainfo(pstapriv, pattrib->src); 444 if (*psta == NULL) 445 return _FAIL; 446 } 447 return _SUCCESS; 448 } 449 450 static sint validate_recv_ctrl_frame(struct _adapter *adapter, 451 union recv_frame *precv_frame) 452 { 453 return _FAIL; 454 } 455 456 static sint validate_recv_mgnt_frame(struct _adapter *adapter, 457 union recv_frame *precv_frame) 458 { 459 return _FAIL; 460 } 461 462 463 static sint validate_recv_data_frame(struct _adapter *adapter, 464 union recv_frame *precv_frame) 465 { 466 int res; 467 u8 bretry; 468 u8 *psa, *pda, *pbssid; 469 struct sta_info *psta = NULL; 470 u8 *ptr = precv_frame->u.hdr.rx_data; 471 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 472 struct security_priv *psecuritypriv = &adapter->securitypriv; 473 474 bretry = GetRetry(ptr); 475 pda = get_da(ptr); 476 psa = get_sa(ptr); 477 pbssid = get_hdr_bssid(ptr); 478 if (pbssid == NULL) 479 return _FAIL; 480 memcpy(pattrib->dst, pda, ETH_ALEN); 481 memcpy(pattrib->src, psa, ETH_ALEN); 482 memcpy(pattrib->bssid, pbssid, ETH_ALEN); 483 switch (pattrib->to_fr_ds) { 484 case 0: 485 memcpy(pattrib->ra, pda, ETH_ALEN); 486 memcpy(pattrib->ta, psa, ETH_ALEN); 487 res = sta2sta_data_frame(adapter, precv_frame, &psta); 488 break; 489 case 1: 490 memcpy(pattrib->ra, pda, ETH_ALEN); 491 memcpy(pattrib->ta, pbssid, ETH_ALEN); 492 res = ap2sta_data_frame(adapter, precv_frame, &psta); 493 break; 494 case 2: 495 memcpy(pattrib->ra, pbssid, ETH_ALEN); 496 memcpy(pattrib->ta, psa, ETH_ALEN); 497 res = sta2ap_data_frame(adapter, precv_frame, &psta); 498 break; 499 case 3: 500 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN); 501 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN); 502 return _FAIL; 503 default: 504 return _FAIL; 505 } 506 if (res == _FAIL) 507 return _FAIL; 508 if (psta == NULL) 509 return _FAIL; 510 precv_frame->u.hdr.psta = psta; 511 pattrib->amsdu = 0; 512 /* parsing QC field */ 513 if (pattrib->qos == 1) { 514 pattrib->priority = GetPriority((ptr + 24)); 515 pattrib->ack_policy = GetAckpolicy((ptr + 24)); 516 pattrib->amsdu = GetAMsdu((ptr + 24)); 517 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26; 518 } else { 519 pattrib->priority = 0; 520 pattrib->hdrlen = (pattrib->to_fr_ds == 3) ? 30 : 24; 521 } 522 523 if (pattrib->order)/*HT-CTRL 11n*/ 524 pattrib->hdrlen += 4; 525 precv_frame->u.hdr.preorder_ctrl = 526 &psta->recvreorder_ctrl[pattrib->priority]; 527 528 /* decache, drop duplicate recv packets */ 529 if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == 530 _FAIL) 531 return _FAIL; 532 533 if (pattrib->privacy) { 534 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, 535 IS_MCAST(pattrib->ra)); 536 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, 537 pattrib->encrypt); 538 } else { 539 pattrib->encrypt = 0; 540 pattrib->iv_len = pattrib->icv_len = 0; 541 } 542 return _SUCCESS; 543 } 544 545 sint r8712_validate_recv_frame(struct _adapter *adapter, 546 union recv_frame *precv_frame) 547 { 548 /*shall check frame subtype, to / from ds, da, bssid */ 549 /*then call check if rx seq/frag. duplicated.*/ 550 551 u8 type; 552 u8 subtype; 553 sint retval = _SUCCESS; 554 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib; 555 556 u8 *ptr = precv_frame->u.hdr.rx_data; 557 u8 ver = (unsigned char)(*ptr) & 0x3; 558 559 /*add version chk*/ 560 if (ver != 0) 561 return _FAIL; 562 type = GetFrameType(ptr); 563 subtype = GetFrameSubType(ptr); /*bit(7)~bit(2)*/ 564 pattrib->to_fr_ds = get_tofr_ds(ptr); 565 pattrib->frag_num = GetFragNum(ptr); 566 pattrib->seq_num = GetSequence(ptr); 567 pattrib->pw_save = GetPwrMgt(ptr); 568 pattrib->mfrag = GetMFrag(ptr); 569 pattrib->mdata = GetMData(ptr); 570 pattrib->privacy = GetPrivacy(ptr); 571 pattrib->order = GetOrder(ptr); 572 switch (type) { 573 case WIFI_MGT_TYPE: /*mgnt*/ 574 retval = validate_recv_mgnt_frame(adapter, precv_frame); 575 break; 576 case WIFI_CTRL_TYPE:/*ctrl*/ 577 retval = validate_recv_ctrl_frame(adapter, precv_frame); 578 break; 579 case WIFI_DATA_TYPE: /*data*/ 580 pattrib->qos = (subtype & BIT(7)) ? 1 : 0; 581 retval = validate_recv_data_frame(adapter, precv_frame); 582 break; 583 default: 584 return _FAIL; 585 } 586 return retval; 587 } 588 589 sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe) 590 { 591 /*remove the wlanhdr and add the eth_hdr*/ 592 sint rmv_len; 593 u16 len; 594 u8 bsnaphdr; 595 u8 *psnap_type; 596 struct ieee80211_snap_hdr *psnap; 597 struct _adapter *adapter = precvframe->u.hdr.adapter; 598 struct mlme_priv *pmlmepriv = &adapter->mlmepriv; 599 600 u8 *ptr = get_recvframe_data(precvframe); /*point to frame_ctrl field*/ 601 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib; 602 603 if (pattrib->encrypt) 604 recvframe_pull_tail(precvframe, pattrib->icv_len); 605 psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + 606 pattrib->iv_len); 607 psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE; 608 /* convert hdr + possible LLC headers into Ethernet header */ 609 if ((!memcmp(psnap, (void *)rfc1042_header, SNAP_SIZE) && 610 (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_IPX, 2)) && 611 (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) || 612 !memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) { 613 /* remove RFC1042 or Bridge-Tunnel encapsulation and 614 * replace EtherType 615 */ 616 bsnaphdr = true; 617 } else { 618 /* Leave Ethernet header part of hdr and full payload */ 619 bsnaphdr = false; 620 } 621 rmv_len = pattrib->hdrlen + pattrib->iv_len + 622 (bsnaphdr ? SNAP_SIZE : 0); 623 len = precvframe->u.hdr.len - rmv_len; 624 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) { 625 ptr += rmv_len; 626 *ptr = 0x87; 627 *(ptr + 1) = 0x12; 628 /* append rx status for mp test packets */ 629 ptr = recvframe_pull(precvframe, (rmv_len - 630 sizeof(struct ethhdr) + 2) - 24); 631 if (!ptr) 632 return _FAIL; 633 memcpy(ptr, get_rxmem(precvframe), 24); 634 ptr += 24; 635 } else { 636 ptr = recvframe_pull(precvframe, (rmv_len - 637 sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0))); 638 if (!ptr) 639 return _FAIL; 640 } 641 642 memcpy(ptr, pattrib->dst, ETH_ALEN); 643 memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN); 644 if (!bsnaphdr) { 645 __be16 be_tmp = htons(len); 646 647 memcpy(ptr + 12, &be_tmp, 2); 648 } 649 return _SUCCESS; 650 } 651 652 s32 r8712_recv_entry(union recv_frame *precvframe) 653 { 654 struct _adapter *padapter; 655 struct recv_priv *precvpriv; 656 657 s32 ret = _SUCCESS; 658 659 padapter = precvframe->u.hdr.adapter; 660 precvpriv = &(padapter->recvpriv); 661 662 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX); 663 664 ret = recv_func(padapter, precvframe); 665 if (ret == _FAIL) 666 goto _recv_entry_drop; 667 precvpriv->rx_pkts++; 668 precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail - 669 precvframe->u.hdr.rx_data); 670 return ret; 671 _recv_entry_drop: 672 precvpriv->rx_drop++; 673 padapter->mppriv.rx_pktloss = precvpriv->rx_drop; 674 return ret; 675 } 676