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