0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #define _RTL871X_RECV_C_
0018
0019 #include <linux/ip.h>
0020 #include <linux/slab.h>
0021 #include <linux/if_ether.h>
0022 #include <linux/kmemleak.h>
0023 #include <linux/etherdevice.h>
0024 #include <linux/ieee80211.h>
0025 #include <net/cfg80211.h>
0026
0027 #include "osdep_service.h"
0028 #include "drv_types.h"
0029 #include "recv_osdep.h"
0030 #include "mlme_osdep.h"
0031 #include "ethernet.h"
0032 #include "usb_ops.h"
0033 #include "wifi.h"
0034
0035 static const u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
0036
0037
0038 static const u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
0039
0040 void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
0041 {
0042 memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
0043 spin_lock_init(&psta_recvpriv->lock);
0044 _init_queue(&psta_recvpriv->defrag_q);
0045 }
0046
0047 void _r8712_init_recv_priv(struct recv_priv *precvpriv,
0048 struct _adapter *padapter)
0049 {
0050 sint i;
0051 union recv_frame *precvframe;
0052
0053 memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv));
0054 spin_lock_init(&precvpriv->lock);
0055 _init_queue(&precvpriv->free_recv_queue);
0056 _init_queue(&precvpriv->recv_pending_queue);
0057 precvpriv->adapter = padapter;
0058 precvpriv->free_recvframe_cnt = NR_RECVFRAME;
0059 precvpriv->pallocated_frame_buf = kzalloc(NR_RECVFRAME *
0060 sizeof(union recv_frame) + RXFRAME_ALIGN_SZ,
0061 GFP_ATOMIC);
0062 if (!precvpriv->pallocated_frame_buf)
0063 return;
0064 kmemleak_not_leak(precvpriv->pallocated_frame_buf);
0065 precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf +
0066 RXFRAME_ALIGN_SZ -
0067 ((addr_t)(precvpriv->pallocated_frame_buf) &
0068 (RXFRAME_ALIGN_SZ - 1));
0069 precvframe = (union recv_frame *)precvpriv->precv_frame_buf;
0070 for (i = 0; i < NR_RECVFRAME; i++) {
0071 INIT_LIST_HEAD(&(precvframe->u.list));
0072 list_add_tail(&(precvframe->u.list),
0073 &(precvpriv->free_recv_queue.queue));
0074 r8712_os_recv_resource_alloc(padapter, precvframe);
0075 precvframe->u.hdr.adapter = padapter;
0076 precvframe++;
0077 }
0078 precvpriv->rx_pending_cnt = 1;
0079 r8712_init_recv_priv(precvpriv, padapter);
0080 }
0081
0082 void _r8712_free_recv_priv(struct recv_priv *precvpriv)
0083 {
0084 kfree(precvpriv->pallocated_frame_buf);
0085 r8712_free_recv_priv(precvpriv);
0086 }
0087
0088 union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue)
0089 {
0090 unsigned long irqL;
0091 union recv_frame *precvframe;
0092 struct _adapter *padapter;
0093 struct recv_priv *precvpriv;
0094
0095 spin_lock_irqsave(&pfree_recv_queue->lock, irqL);
0096 precvframe = list_first_entry_or_null(&pfree_recv_queue->queue,
0097 union recv_frame, u.hdr.list);
0098 if (precvframe) {
0099 list_del_init(&precvframe->u.hdr.list);
0100 padapter = precvframe->u.hdr.adapter;
0101 if (padapter) {
0102 precvpriv = &padapter->recvpriv;
0103 if (pfree_recv_queue == &precvpriv->free_recv_queue)
0104 precvpriv->free_recvframe_cnt--;
0105 }
0106 }
0107 spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL);
0108 return precvframe;
0109 }
0110
0111
0112
0113
0114
0115
0116 void r8712_free_recvframe_queue(struct __queue *pframequeue,
0117 struct __queue *pfree_recv_queue)
0118 {
0119 union recv_frame *precvframe;
0120 struct list_head *plist, *phead;
0121
0122 spin_lock(&pframequeue->lock);
0123 phead = &pframequeue->queue;
0124 plist = phead->next;
0125 while (!end_of_queue_search(phead, plist)) {
0126 precvframe = container_of(plist, union recv_frame, u.list);
0127 plist = plist->next;
0128 r8712_free_recvframe(precvframe, pfree_recv_queue);
0129 }
0130 spin_unlock(&pframequeue->lock);
0131 }
0132
0133 sint r8712_recvframe_chkmic(struct _adapter *adapter,
0134 union recv_frame *precvframe)
0135 {
0136 sint i, res = _SUCCESS;
0137 u32 datalen;
0138 u8 miccode[8];
0139 u8 bmic_err = false;
0140 u8 *pframe, *payload, *pframemic;
0141 u8 *mickey, idx, *iv;
0142 struct sta_info *stainfo;
0143 struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib;
0144 struct security_priv *psecuritypriv = &adapter->securitypriv;
0145
0146 stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
0147 if (prxattrib->encrypt == _TKIP_) {
0148
0149 if (stainfo) {
0150 if (is_multicast_ether_addr(prxattrib->ra)) {
0151 iv = precvframe->u.hdr.rx_data +
0152 prxattrib->hdrlen;
0153 idx = iv[3];
0154 mickey = &psecuritypriv->XGrprxmickey[(((idx >>
0155 6) & 0x3)) - 1].skey[0];
0156 if (!psecuritypriv->binstallGrpkey)
0157 return _FAIL;
0158 } else {
0159 mickey = &stainfo->tkiprxmickey.skey[0];
0160 }
0161
0162 datalen = precvframe->u.hdr.len - prxattrib->hdrlen -
0163 prxattrib->iv_len - prxattrib->icv_len - 8;
0164 pframe = precvframe->u.hdr.rx_data;
0165 payload = pframe + prxattrib->hdrlen +
0166 prxattrib->iv_len;
0167 seccalctkipmic(mickey, pframe, payload, datalen,
0168 &miccode[0],
0169 (unsigned char)prxattrib->priority);
0170 pframemic = payload + datalen;
0171 bmic_err = false;
0172 for (i = 0; i < 8; i++) {
0173 if (miccode[i] != *(pframemic + i))
0174 bmic_err = true;
0175 }
0176 if (bmic_err) {
0177 if (prxattrib->bdecrypted)
0178 r8712_handle_tkip_mic_err(adapter,
0179 (u8)is_multicast_ether_addr(prxattrib->ra));
0180 res = _FAIL;
0181 } else {
0182
0183 if (!psecuritypriv->bcheck_grpkey &&
0184 is_multicast_ether_addr(prxattrib->ra))
0185 psecuritypriv->bcheck_grpkey = true;
0186 }
0187 recvframe_pull_tail(precvframe, 8);
0188 }
0189 }
0190 return res;
0191 }
0192
0193
0194 union recv_frame *r8712_decryptor(struct _adapter *padapter,
0195 union recv_frame *precv_frame)
0196 {
0197 struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
0198 struct security_priv *psecuritypriv = &padapter->securitypriv;
0199 union recv_frame *return_packet = precv_frame;
0200
0201 if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) ||
0202 psecuritypriv->sw_decrypt)) {
0203 psecuritypriv->hw_decrypted = false;
0204 switch (prxattrib->encrypt) {
0205 case _WEP40_:
0206 case _WEP104_:
0207 r8712_wep_decrypt(padapter, (u8 *)precv_frame);
0208 break;
0209 case _TKIP_:
0210 r8712_tkip_decrypt(padapter, (u8 *)precv_frame);
0211 break;
0212 case _AES_:
0213 r8712_aes_decrypt(padapter, (u8 *)precv_frame);
0214 break;
0215 default:
0216 break;
0217 }
0218 } else if (prxattrib->bdecrypted == 1) {
0219 psecuritypriv->hw_decrypted = true;
0220 }
0221 return return_packet;
0222 }
0223
0224
0225 union recv_frame *r8712_portctrl(struct _adapter *adapter,
0226 union recv_frame *precv_frame)
0227 {
0228 u8 *psta_addr, *ptr;
0229 uint auth_alg;
0230 struct recv_frame_hdr *pfhdr;
0231 struct sta_info *psta;
0232 struct sta_priv *pstapriv;
0233 union recv_frame *prtnframe;
0234 u16 ether_type;
0235
0236 pstapriv = &adapter->stapriv;
0237 ptr = precv_frame->u.hdr.rx_data;
0238 pfhdr = &precv_frame->u.hdr;
0239 psta_addr = pfhdr->attrib.ta;
0240 psta = r8712_get_stainfo(pstapriv, psta_addr);
0241 auth_alg = adapter->securitypriv.AuthAlgrthm;
0242 if (auth_alg == 2) {
0243
0244 ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
0245 ether_type = get_unaligned_be16(ptr);
0246
0247 if (psta && psta->ieee8021x_blocked) {
0248
0249
0250
0251 if (ether_type == 0x888e) {
0252 prtnframe = precv_frame;
0253 } else {
0254
0255 r8712_free_recvframe(precv_frame,
0256 &adapter->recvpriv.free_recv_queue);
0257 prtnframe = NULL;
0258 }
0259 } else {
0260
0261
0262
0263
0264 prtnframe = precv_frame;
0265
0266 if (ether_type == 0x888e) {
0267
0268 prtnframe = precv_frame;
0269 }
0270 }
0271 } else {
0272 prtnframe = precv_frame;
0273 }
0274 return prtnframe;
0275 }
0276
0277 static sint recv_decache(union recv_frame *precv_frame, u8 bretry,
0278 struct stainfo_rxcache *prxcache)
0279 {
0280 sint tid = precv_frame->u.hdr.attrib.priority;
0281 u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) |
0282 (precv_frame->u.hdr.attrib.frag_num & 0xf);
0283
0284 if (tid > 15)
0285 return _FAIL;
0286 if (seq_ctrl == prxcache->tid_rxseq[tid])
0287 return _FAIL;
0288 prxcache->tid_rxseq[tid] = seq_ctrl;
0289 return _SUCCESS;
0290 }
0291
0292 static sint sta2sta_data_frame(struct _adapter *adapter,
0293 union recv_frame *precv_frame,
0294 struct sta_info **psta)
0295 {
0296 u8 *ptr = precv_frame->u.hdr.rx_data;
0297 sint ret = _SUCCESS;
0298 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
0299 struct sta_priv *pstapriv = &adapter->stapriv;
0300 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
0301 u8 *mybssid = get_bssid(pmlmepriv);
0302 u8 *myhwaddr = myid(&adapter->eeprompriv);
0303 u8 *sta_addr = NULL;
0304 bool bmcast = is_multicast_ether_addr(pattrib->dst);
0305
0306 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
0307 check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
0308
0309 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN))
0310 return _FAIL;
0311 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast))
0312 return _FAIL;
0313 if (is_zero_ether_addr(pattrib->bssid) ||
0314 is_zero_ether_addr(mybssid) ||
0315 (memcmp(pattrib->bssid, mybssid, ETH_ALEN)))
0316 return _FAIL;
0317 sta_addr = pattrib->src;
0318 } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
0319
0320
0321
0322 if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN))
0323 return _FAIL;
0324 sta_addr = pattrib->bssid;
0325 } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
0326 if (bmcast) {
0327
0328
0329
0330 if (!is_multicast_ether_addr(pattrib->bssid))
0331 return _FAIL;
0332 } else {
0333
0334
0335
0336 if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN))
0337 return _FAIL;
0338 sta_addr = pattrib->src;
0339 }
0340 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
0341 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
0342 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
0343 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
0344 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
0345 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
0346 sta_addr = mybssid;
0347 } else {
0348 ret = _FAIL;
0349 }
0350 if (bmcast)
0351 *psta = r8712_get_bcmc_stainfo(adapter);
0352 else
0353 *psta = r8712_get_stainfo(pstapriv, sta_addr);
0354 if (!*psta) {
0355 if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
0356 adapter->mppriv.rx_pktloss++;
0357 return _FAIL;
0358 }
0359 return ret;
0360 }
0361
0362 static sint ap2sta_data_frame(struct _adapter *adapter,
0363 union recv_frame *precv_frame,
0364 struct sta_info **psta)
0365 {
0366 u8 *ptr = precv_frame->u.hdr.rx_data;
0367 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
0368 struct sta_priv *pstapriv = &adapter->stapriv;
0369 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
0370 u8 *mybssid = get_bssid(pmlmepriv);
0371 u8 *myhwaddr = myid(&adapter->eeprompriv);
0372 bool bmcast = is_multicast_ether_addr(pattrib->dst);
0373
0374 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
0375 check_fwstate(pmlmepriv, _FW_LINKED)) {
0376
0377 if ((GetFrameSubType(ptr)) == (IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC))
0378 return _FAIL;
0379
0380
0381
0382 if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) ==
0383 WIFI_QOS_DATA_TYPE) {
0384 if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6)))
0385 return _FAIL;
0386 }
0387
0388
0389 if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN))
0390 return _FAIL;
0391
0392
0393 if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast))
0394 return _FAIL;
0395
0396 if (is_zero_ether_addr(pattrib->bssid) ||
0397 is_zero_ether_addr(mybssid) ||
0398 (memcmp(pattrib->bssid, mybssid, ETH_ALEN)))
0399 return _FAIL;
0400 if (bmcast)
0401 *psta = r8712_get_bcmc_stainfo(adapter);
0402 else
0403 *psta = r8712_get_stainfo(pstapriv, pattrib->bssid);
0404 if (!*psta)
0405 return _FAIL;
0406 } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
0407 check_fwstate(pmlmepriv, _FW_LINKED)) {
0408 memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
0409 memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
0410 memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
0411 memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
0412 memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
0413 memcpy(pattrib->bssid, mybssid, ETH_ALEN);
0414 *psta = r8712_get_stainfo(pstapriv, pattrib->bssid);
0415 if (!*psta)
0416 return _FAIL;
0417 } else {
0418 return _FAIL;
0419 }
0420 return _SUCCESS;
0421 }
0422
0423 static sint sta2ap_data_frame(struct _adapter *adapter,
0424 union recv_frame *precv_frame,
0425 struct sta_info **psta)
0426 {
0427 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
0428 struct sta_priv *pstapriv = &adapter->stapriv;
0429 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
0430 unsigned char *mybssid = get_bssid(pmlmepriv);
0431
0432 if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
0433
0434
0435
0436
0437 if (memcmp(pattrib->bssid, mybssid, ETH_ALEN))
0438 return _FAIL;
0439 *psta = r8712_get_stainfo(pstapriv, pattrib->src);
0440 if (!*psta)
0441 return _FAIL;
0442 }
0443 return _SUCCESS;
0444 }
0445
0446 static sint validate_recv_ctrl_frame(struct _adapter *adapter,
0447 union recv_frame *precv_frame)
0448 {
0449 return _FAIL;
0450 }
0451
0452 static sint validate_recv_mgnt_frame(struct _adapter *adapter,
0453 union recv_frame *precv_frame)
0454 {
0455 return _FAIL;
0456 }
0457
0458 static sint validate_recv_data_frame(struct _adapter *adapter,
0459 union recv_frame *precv_frame)
0460 {
0461 int res;
0462 u8 bretry;
0463 u8 *psa, *pda, *pbssid;
0464 struct sta_info *psta = NULL;
0465 u8 *ptr = precv_frame->u.hdr.rx_data;
0466 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
0467 struct security_priv *psecuritypriv = &adapter->securitypriv;
0468
0469 bretry = GetRetry(ptr);
0470 pda = ieee80211_get_DA((struct ieee80211_hdr *)ptr);
0471 psa = ieee80211_get_SA((struct ieee80211_hdr *)ptr);
0472 pbssid = get_hdr_bssid(ptr);
0473 if (!pbssid)
0474 return _FAIL;
0475 memcpy(pattrib->dst, pda, ETH_ALEN);
0476 memcpy(pattrib->src, psa, ETH_ALEN);
0477 memcpy(pattrib->bssid, pbssid, ETH_ALEN);
0478 switch (pattrib->to_fr_ds) {
0479 case 0:
0480 memcpy(pattrib->ra, pda, ETH_ALEN);
0481 memcpy(pattrib->ta, psa, ETH_ALEN);
0482 res = sta2sta_data_frame(adapter, precv_frame, &psta);
0483 break;
0484 case 1:
0485 memcpy(pattrib->ra, pda, ETH_ALEN);
0486 memcpy(pattrib->ta, pbssid, ETH_ALEN);
0487 res = ap2sta_data_frame(adapter, precv_frame, &psta);
0488 break;
0489 case 2:
0490 memcpy(pattrib->ra, pbssid, ETH_ALEN);
0491 memcpy(pattrib->ta, psa, ETH_ALEN);
0492 res = sta2ap_data_frame(adapter, precv_frame, &psta);
0493 break;
0494 case 3:
0495 memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
0496 memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
0497 return _FAIL;
0498 default:
0499 return _FAIL;
0500 }
0501 if (res == _FAIL)
0502 return _FAIL;
0503 if (!psta)
0504 return _FAIL;
0505 precv_frame->u.hdr.psta = psta;
0506 pattrib->amsdu = 0;
0507
0508 if (pattrib->qos == 1) {
0509 pattrib->priority = GetPriority((ptr + 24));
0510 pattrib->ack_policy = GetAckpolicy((ptr + 24));
0511 pattrib->amsdu = GetAMsdu((ptr + 24));
0512 pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
0513 } else {
0514 pattrib->priority = 0;
0515 pattrib->hdrlen = (pattrib->to_fr_ds == 3) ? 30 : 24;
0516 }
0517
0518 if (pattrib->order)
0519 pattrib->hdrlen += 4;
0520 precv_frame->u.hdr.preorder_ctrl =
0521 &psta->recvreorder_ctrl[pattrib->priority];
0522
0523
0524 if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
0525 _FAIL)
0526 return _FAIL;
0527
0528 if (pattrib->privacy) {
0529 GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
0530 is_multicast_ether_addr(pattrib->ra));
0531 SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len,
0532 pattrib->encrypt);
0533 } else {
0534 pattrib->encrypt = 0;
0535 pattrib->iv_len = pattrib->icv_len = 0;
0536 }
0537 return _SUCCESS;
0538 }
0539
0540 sint r8712_validate_recv_frame(struct _adapter *adapter,
0541 union recv_frame *precv_frame)
0542 {
0543
0544
0545
0546 u8 type;
0547 u8 subtype;
0548 sint retval = _SUCCESS;
0549 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
0550
0551 u8 *ptr = precv_frame->u.hdr.rx_data;
0552 u8 ver = (unsigned char)(*ptr) & 0x3;
0553
0554
0555 if (ver != 0)
0556 return _FAIL;
0557 type = GetFrameType(ptr);
0558 subtype = GetFrameSubType(ptr);
0559 pattrib->to_fr_ds = get_tofr_ds(ptr);
0560 pattrib->frag_num = GetFragNum(ptr);
0561 pattrib->seq_num = GetSequence(ptr);
0562 pattrib->pw_save = GetPwrMgt(ptr);
0563 pattrib->mfrag = GetMFrag(ptr);
0564 pattrib->mdata = GetMData(ptr);
0565 pattrib->privacy = GetPrivacy(ptr);
0566 pattrib->order = GetOrder(ptr);
0567 switch (type) {
0568 case IEEE80211_FTYPE_MGMT:
0569 retval = validate_recv_mgnt_frame(adapter, precv_frame);
0570 break;
0571 case IEEE80211_FTYPE_CTL:
0572 retval = validate_recv_ctrl_frame(adapter, precv_frame);
0573 break;
0574 case IEEE80211_FTYPE_DATA:
0575 pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
0576 retval = validate_recv_data_frame(adapter, precv_frame);
0577 break;
0578 default:
0579 return _FAIL;
0580 }
0581 return retval;
0582 }
0583
0584 int r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
0585 {
0586
0587 sint rmv_len;
0588 u16 len;
0589 u8 bsnaphdr;
0590 u8 *psnap_type;
0591 struct ieee80211_snap_hdr *psnap;
0592 struct _adapter *adapter = precvframe->u.hdr.adapter;
0593 struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
0594
0595 u8 *ptr = precvframe->u.hdr.rx_data;
0596 struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
0597
0598 if (pattrib->encrypt)
0599 recvframe_pull_tail(precvframe, pattrib->icv_len);
0600 psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen +
0601 pattrib->iv_len);
0602 psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
0603
0604 if ((!memcmp(psnap, (void *)rfc1042_header, SNAP_SIZE) &&
0605 (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_IPX, 2)) &&
0606 (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) ||
0607 !memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) {
0608
0609
0610
0611 bsnaphdr = true;
0612 } else {
0613
0614 bsnaphdr = false;
0615 }
0616 rmv_len = pattrib->hdrlen + pattrib->iv_len +
0617 (bsnaphdr ? SNAP_SIZE : 0);
0618 len = precvframe->u.hdr.len - rmv_len;
0619 if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
0620 ptr += rmv_len;
0621 *ptr = 0x87;
0622 *(ptr + 1) = 0x12;
0623
0624 ptr = recvframe_pull(precvframe, (rmv_len -
0625 sizeof(struct ethhdr) + 2) - 24);
0626 if (!ptr)
0627 return -ENOMEM;
0628 memcpy(ptr, get_rxmem(precvframe), 24);
0629 ptr += 24;
0630 } else {
0631 ptr = recvframe_pull(precvframe, (rmv_len -
0632 sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
0633 if (!ptr)
0634 return -ENOMEM;
0635 }
0636
0637 memcpy(ptr, pattrib->dst, ETH_ALEN);
0638 memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
0639 if (!bsnaphdr) {
0640 __be16 be_tmp = htons(len);
0641
0642 memcpy(ptr + 12, &be_tmp, 2);
0643 }
0644 return 0;
0645 }
0646
0647 void r8712_recv_entry(union recv_frame *precvframe)
0648 {
0649 struct _adapter *padapter;
0650 struct recv_priv *precvpriv;
0651
0652 s32 ret = _SUCCESS;
0653
0654 padapter = precvframe->u.hdr.adapter;
0655 precvpriv = &(padapter->recvpriv);
0656
0657 padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX);
0658
0659 ret = recv_func(padapter, precvframe);
0660 if (ret == _FAIL)
0661 goto _recv_entry_drop;
0662 precvpriv->rx_pkts++;
0663 precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail -
0664 precvframe->u.hdr.rx_data);
0665 return;
0666 _recv_entry_drop:
0667 precvpriv->rx_drop++;
0668 padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
0669 }