linux/drivers/staging/r8188eu/core/rtw_recv.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2007 - 2012 Realtek Corporation. */
   3
   4#define _RTW_RECV_C_
   5
   6#include "../include/osdep_service.h"
   7#include "../include/drv_types.h"
   8#include "../include/recv_osdep.h"
   9#include "../include/mlme_osdep.h"
  10#include "../include/usb_ops.h"
  11#include "../include/wifi.h"
  12
  13static u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
  14static u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
  15
  16/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
  17static u8 rtw_bridge_tunnel_header[] = {
  18       0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8
  19};
  20
  21static u8 rtw_rfc1042_header[] = {
  22       0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00
  23};
  24
  25void rtw_signal_stat_timer_hdl(struct timer_list *);
  26
  27void _rtw_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
  28{
  29
  30        memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
  31
  32        spin_lock_init(&psta_recvpriv->lock);
  33
  34        _rtw_init_queue(&psta_recvpriv->defrag_q);
  35
  36}
  37
  38int _rtw_init_recv_priv(struct recv_priv *precvpriv, struct adapter *padapter)
  39{
  40        int i;
  41
  42        struct recv_frame *precvframe;
  43
  44        int     res = _SUCCESS;
  45
  46        spin_lock_init(&precvpriv->lock);
  47
  48        _rtw_init_queue(&precvpriv->free_recv_queue);
  49        _rtw_init_queue(&precvpriv->recv_pending_queue);
  50        _rtw_init_queue(&precvpriv->uc_swdec_pending_queue);
  51
  52        precvpriv->adapter = padapter;
  53
  54        precvpriv->free_recvframe_cnt = NR_RECVFRAME;
  55
  56        rtw_os_recv_resource_init(precvpriv, padapter);
  57
  58        precvpriv->pallocated_frame_buf = vzalloc(NR_RECVFRAME * sizeof(struct recv_frame) + RXFRAME_ALIGN_SZ);
  59
  60        if (!precvpriv->pallocated_frame_buf) {
  61                res = _FAIL;
  62                goto exit;
  63        }
  64
  65        precvpriv->precv_frame_buf = (u8 *)N_BYTE_ALIGMENT((size_t)(precvpriv->pallocated_frame_buf), RXFRAME_ALIGN_SZ);
  66
  67        precvframe = (struct recv_frame *)precvpriv->precv_frame_buf;
  68
  69        for (i = 0; i < NR_RECVFRAME; i++) {
  70                INIT_LIST_HEAD(&precvframe->list);
  71
  72                list_add_tail(&precvframe->list, &precvpriv->free_recv_queue.queue);
  73
  74                res = rtw_os_recv_resource_alloc(padapter, precvframe);
  75
  76                precvframe->len = 0;
  77
  78                precvframe->adapter = padapter;
  79                precvframe++;
  80        }
  81        precvpriv->rx_pending_cnt = 1;
  82
  83        sema_init(&precvpriv->allrxreturnevt, 0);
  84
  85        res = rtw_hal_init_recv_priv(padapter);
  86
  87        timer_setup(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl, 0);
  88        precvpriv->signal_stat_sampling_interval = 1000; /* ms */
  89
  90        rtw_set_signal_stat_timer(precvpriv);
  91exit:
  92
  93        return res;
  94}
  95
  96void _rtw_free_recv_priv(struct recv_priv *precvpriv)
  97{
  98        struct adapter  *padapter = precvpriv->adapter;
  99
 100        rtw_free_uc_swdec_pending_queue(padapter);
 101
 102        rtw_os_recv_resource_free(precvpriv);
 103
 104        vfree(precvpriv->pallocated_frame_buf);
 105
 106        rtw_hal_free_recv_priv(padapter);
 107}
 108
 109struct recv_frame *_rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
 110{
 111        struct recv_frame *hdr;
 112        struct list_head *plist, *phead;
 113        struct adapter *padapter;
 114        struct recv_priv *precvpriv;
 115
 116        if (list_empty(&pfree_recv_queue->queue)) {
 117                hdr = NULL;
 118        } else {
 119                phead = get_list_head(pfree_recv_queue);
 120
 121                plist = phead->next;
 122
 123                hdr = container_of(plist, struct recv_frame, list);
 124
 125                list_del_init(&hdr->list);
 126                padapter = hdr->adapter;
 127                if (padapter) {
 128                        precvpriv = &padapter->recvpriv;
 129                        if (pfree_recv_queue == &precvpriv->free_recv_queue)
 130                                precvpriv->free_recvframe_cnt--;
 131                }
 132        }
 133
 134        return (struct recv_frame *)hdr;
 135}
 136
 137struct recv_frame *rtw_alloc_recvframe(struct __queue *pfree_recv_queue)
 138{
 139        struct recv_frame  *precvframe;
 140
 141        spin_lock_bh(&pfree_recv_queue->lock);
 142
 143        precvframe = _rtw_alloc_recvframe(pfree_recv_queue);
 144
 145        spin_unlock_bh(&pfree_recv_queue->lock);
 146
 147        return precvframe;
 148}
 149
 150void rtw_init_recvframe(struct recv_frame *precvframe, struct recv_priv *precvpriv)
 151{
 152        /* Perry: This can be removed */
 153        INIT_LIST_HEAD(&precvframe->list);
 154
 155        precvframe->len = 0;
 156}
 157
 158int rtw_free_recvframe(struct recv_frame *precvframe, struct __queue *pfree_recv_queue)
 159{
 160        struct adapter *padapter;
 161        struct recv_priv *precvpriv;
 162
 163        if (!precvframe)
 164                return _FAIL;
 165        padapter = precvframe->adapter;
 166        precvpriv = &padapter->recvpriv;
 167        if (precvframe->pkt) {
 168                dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */
 169                precvframe->pkt = NULL;
 170        }
 171
 172        spin_lock_bh(&pfree_recv_queue->lock);
 173
 174        list_del_init(&precvframe->list);
 175
 176        precvframe->len = 0;
 177
 178        list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
 179
 180        if (padapter) {
 181                if (pfree_recv_queue == &precvpriv->free_recv_queue)
 182                                precvpriv->free_recvframe_cnt++;
 183        }
 184
 185        spin_unlock_bh(&pfree_recv_queue->lock);
 186
 187        return _SUCCESS;
 188}
 189
 190int _rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue)
 191{
 192        struct adapter *padapter = precvframe->adapter;
 193        struct recv_priv *precvpriv = &padapter->recvpriv;
 194
 195        list_del_init(&precvframe->list);
 196        list_add_tail(&precvframe->list, get_list_head(queue));
 197
 198        if (padapter) {
 199                if (queue == &precvpriv->free_recv_queue)
 200                        precvpriv->free_recvframe_cnt++;
 201        }
 202
 203        return _SUCCESS;
 204}
 205
 206int rtw_enqueue_recvframe(struct recv_frame *precvframe, struct __queue *queue)
 207{
 208        int ret;
 209
 210        spin_lock_bh(&queue->lock);
 211        ret = _rtw_enqueue_recvframe(precvframe, queue);
 212        spin_unlock_bh(&queue->lock);
 213
 214        return ret;
 215}
 216
 217/*
 218caller : defrag ; recvframe_chk_defrag in recv_thread  (passive)
 219pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
 220
 221using spinlock to protect
 222
 223*/
 224
 225void rtw_free_recvframe_queue(struct __queue *pframequeue,  struct __queue *pfree_recv_queue)
 226{
 227        struct recv_frame *hdr;
 228        struct list_head *plist, *phead;
 229
 230        spin_lock(&pframequeue->lock);
 231
 232        phead = get_list_head(pframequeue);
 233        plist = phead->next;
 234
 235        while (phead != plist) {
 236                hdr = container_of(plist, struct recv_frame, list);
 237
 238                plist = plist->next;
 239
 240                rtw_free_recvframe((struct recv_frame *)hdr, pfree_recv_queue);
 241        }
 242
 243        spin_unlock(&pframequeue->lock);
 244
 245}
 246
 247u32 rtw_free_uc_swdec_pending_queue(struct adapter *adapter)
 248{
 249        u32 cnt = 0;
 250        struct recv_frame *pending_frame;
 251        while ((pending_frame = rtw_alloc_recvframe(&adapter->recvpriv.uc_swdec_pending_queue))) {
 252                rtw_free_recvframe(pending_frame, &adapter->recvpriv.free_recv_queue);
 253                DBG_88E("%s: dequeue uc_swdec_pending_queue\n", __func__);
 254                cnt++;
 255        }
 256
 257        return cnt;
 258}
 259
 260int rtw_enqueue_recvbuf_to_head(struct recv_buf *precvbuf, struct __queue *queue)
 261{
 262        spin_lock_bh(&queue->lock);
 263
 264        list_del_init(&precvbuf->list);
 265        list_add(&precvbuf->list, get_list_head(queue));
 266
 267        spin_unlock_bh(&queue->lock);
 268
 269        return _SUCCESS;
 270}
 271
 272int rtw_enqueue_recvbuf(struct recv_buf *precvbuf, struct __queue *queue)
 273{
 274        unsigned long flags;
 275
 276        spin_lock_irqsave(&queue->lock, flags);
 277
 278        list_del_init(&precvbuf->list);
 279
 280        list_add_tail(&precvbuf->list, get_list_head(queue));
 281        spin_unlock_irqrestore(&queue->lock, flags);
 282        return _SUCCESS;
 283}
 284
 285struct recv_buf *rtw_dequeue_recvbuf(struct __queue *queue)
 286{
 287        struct recv_buf *precvbuf;
 288        struct list_head *plist, *phead;
 289        unsigned long flags;
 290
 291        spin_lock_irqsave(&queue->lock, flags);
 292
 293        if (list_empty(&queue->queue)) {
 294                precvbuf = NULL;
 295        } else {
 296                phead = get_list_head(queue);
 297
 298                plist = phead->next;
 299
 300                precvbuf = container_of(plist, struct recv_buf, list);
 301
 302                list_del_init(&precvbuf->list);
 303        }
 304
 305        spin_unlock_irqrestore(&queue->lock, flags);
 306
 307        return precvbuf;
 308}
 309
 310static int recvframe_chkmic(struct adapter *adapter,  struct recv_frame *precvframe)
 311{
 312        int     i, res = _SUCCESS;
 313        u32     datalen;
 314        u8      miccode[8];
 315        u8      bmic_err = false, brpt_micerror = true;
 316        u8      *pframe, *payload, *pframemic;
 317        u8      *mickey;
 318        struct  sta_info                *stainfo;
 319        struct  rx_pkt_attrib   *prxattrib = &precvframe->attrib;
 320        struct  security_priv   *psecuritypriv = &adapter->securitypriv;
 321
 322        struct mlme_ext_priv    *pmlmeext = &adapter->mlmeextpriv;
 323        struct mlme_ext_info    *pmlmeinfo = &pmlmeext->mlmext_info;
 324
 325        stainfo = rtw_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
 326
 327        if (prxattrib->encrypt == _TKIP_) {
 328                /* calculate mic code */
 329                if (stainfo) {
 330                        if (is_multicast_ether_addr(prxattrib->ra)) {
 331                                mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
 332
 333                                if (!psecuritypriv) {
 334                                        res = _FAIL;
 335                                        DBG_88E("\n recvframe_chkmic:didn't install group key!!!!!!!!!!\n");
 336                                        goto exit;
 337                                }
 338                        } else {
 339                                mickey = &stainfo->dot11tkiprxmickey.skey[0];
 340                        }
 341
 342                        datalen = precvframe->len - prxattrib->hdrlen - prxattrib->iv_len - prxattrib->icv_len - 8;/* icv_len included the mic code */
 343                        pframe = precvframe->rx_data;
 344                        payload = pframe + prxattrib->hdrlen + prxattrib->iv_len;
 345
 346                        rtw_seccalctkipmic(mickey, pframe, payload, datalen, &miccode[0],
 347                                           (unsigned char)prxattrib->priority); /* care the length of the data */
 348
 349                        pframemic = payload + datalen;
 350
 351                        bmic_err = false;
 352
 353                        for (i = 0; i < 8; i++) {
 354                                if (miccode[i] != *(pframemic + i))
 355                                        bmic_err = true;
 356                        }
 357
 358                        if (bmic_err) {
 359                                /*  double check key_index for some timing issue , */
 360                                /*  cannot compare with psecuritypriv->dot118021XGrpKeyid also cause timing issue */
 361                                if (is_multicast_ether_addr(prxattrib->ra) && prxattrib->key_index != pmlmeinfo->key_index)
 362                                        brpt_micerror = false;
 363
 364                                if ((prxattrib->bdecrypted) && (brpt_micerror)) {
 365                                        rtw_handle_tkip_mic_err(adapter, (u8)is_multicast_ether_addr(prxattrib->ra));
 366                                        DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
 367                                } else {
 368                                        DBG_88E(" mic error :prxattrib->bdecrypted=%d\n", prxattrib->bdecrypted);
 369                                }
 370                                res = _FAIL;
 371                        } else {
 372                                /* mic checked ok */
 373                                if (!psecuritypriv->bcheck_grpkey && is_multicast_ether_addr(prxattrib->ra))
 374                                        psecuritypriv->bcheck_grpkey = true;
 375                        }
 376                }
 377
 378                recvframe_pull_tail(precvframe, 8);
 379        }
 380
 381exit:
 382
 383        return res;
 384}
 385
 386/* decrypt and set the ivlen, icvlen of the recv_frame */
 387static struct recv_frame *decryptor(struct adapter *padapter, struct recv_frame *precv_frame)
 388{
 389        struct rx_pkt_attrib *prxattrib = &precv_frame->attrib;
 390        struct security_priv *psecuritypriv = &padapter->securitypriv;
 391        struct recv_frame *return_packet = precv_frame;
 392        u32      res = _SUCCESS;
 393
 394        if (prxattrib->encrypt > 0) {
 395                u8 *iv = precv_frame->rx_data + prxattrib->hdrlen;
 396                prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
 397
 398                if (prxattrib->key_index > WEP_KEYS) {
 399                        DBG_88E("prxattrib->key_index(%d)>WEP_KEYS\n", prxattrib->key_index);
 400
 401                        switch (prxattrib->encrypt) {
 402                        case _WEP40_:
 403                        case _WEP104_:
 404                                prxattrib->key_index = psecuritypriv->dot11PrivacyKeyIndex;
 405                                break;
 406                        case _TKIP_:
 407                        case _AES_:
 408                        default:
 409                                prxattrib->key_index = psecuritypriv->dot118021XGrpKeyid;
 410                                break;
 411                        }
 412                }
 413        }
 414
 415        if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) || (psecuritypriv->sw_decrypt))) {
 416                psecuritypriv->hw_decrypted = false;
 417
 418                switch (prxattrib->encrypt) {
 419                case _WEP40_:
 420                case _WEP104_:
 421                        rtw_wep_decrypt(padapter, (u8 *)precv_frame);
 422                        break;
 423                case _TKIP_:
 424                        res = rtw_tkip_decrypt(padapter, (u8 *)precv_frame);
 425                        break;
 426                case _AES_:
 427                        res = rtw_aes_decrypt(padapter, (u8 *)precv_frame);
 428                        break;
 429                default:
 430                        break;
 431                }
 432        } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 &&
 433                   (psecuritypriv->busetkipkey == 1 || prxattrib->encrypt != _TKIP_))
 434                        psecuritypriv->hw_decrypted = true;
 435
 436        if (res == _FAIL) {
 437                rtw_free_recvframe(return_packet, &padapter->recvpriv.free_recv_queue);
 438                return_packet = NULL;
 439        } else {
 440                prxattrib->bdecrypted = true;
 441        }
 442
 443        return return_packet;
 444}
 445
 446/* set the security information in the recv_frame */
 447static struct recv_frame *portctrl(struct adapter *adapter, struct recv_frame *precv_frame)
 448{
 449        u8   *psta_addr, *ptr;
 450        uint  auth_alg;
 451        struct recv_frame *pfhdr;
 452        struct sta_info *psta;
 453        struct sta_priv *pstapriv;
 454        struct recv_frame *prtnframe;
 455        u16 ether_type = 0;
 456        u16  eapol_type = 0x888e;/* for Funia BD's WPA issue */
 457        struct rx_pkt_attrib *pattrib;
 458        __be16 be_tmp;
 459
 460        pstapriv = &adapter->stapriv;
 461
 462        auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
 463
 464        ptr = precv_frame->rx_data;
 465        pfhdr = precv_frame;
 466        pattrib = &pfhdr->attrib;
 467        psta_addr = pattrib->ta;
 468
 469        prtnframe = NULL;
 470
 471        psta = rtw_get_stainfo(pstapriv, psta_addr);
 472
 473        if (auth_alg == 2) {
 474                if (psta && psta->ieee8021x_blocked) {
 475                        /* blocked */
 476                        /* only accept EAPOL frame */
 477                        prtnframe = precv_frame;
 478
 479                        /* get ether_type */
 480                        ptr = ptr + pfhdr->attrib.hdrlen + pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
 481                        memcpy(&be_tmp, ptr, 2);
 482                        ether_type = ntohs(be_tmp);
 483
 484                        if (ether_type == eapol_type) {
 485                                prtnframe = precv_frame;
 486                        } else {
 487                                /* free this frame */
 488                                rtw_free_recvframe(precv_frame, &adapter->recvpriv.free_recv_queue);
 489                                prtnframe = NULL;
 490                        }
 491                } else {
 492                        /* allowed */
 493                        /* check decryption status, and decrypt the frame if needed */
 494                        prtnframe = precv_frame;
 495                }
 496        } else {
 497                prtnframe = precv_frame;
 498        }
 499
 500        return prtnframe;
 501}
 502
 503static int recv_decache(struct recv_frame *precv_frame, u8 bretry, struct stainfo_rxcache *prxcache)
 504{
 505        int tid = precv_frame->attrib.priority;
 506
 507        u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) |
 508                (precv_frame->attrib.frag_num & 0xf);
 509
 510        if (tid > 15)
 511                return _FAIL;
 512
 513        if (1) {/* if (bretry) */
 514                if (seq_ctrl == prxcache->tid_rxseq[tid])
 515                        return _FAIL;
 516        }
 517
 518        prxcache->tid_rxseq[tid] = seq_ctrl;
 519
 520        return _SUCCESS;
 521}
 522
 523void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame);
 524void process_pwrbit_data(struct adapter *padapter, struct recv_frame *precv_frame)
 525{
 526#ifdef CONFIG_88EU_AP_MODE
 527        unsigned char pwrbit;
 528        u8 *ptr = precv_frame->rx_data;
 529        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 530        struct sta_priv *pstapriv = &padapter->stapriv;
 531        struct sta_info *psta = NULL;
 532
 533        psta = rtw_get_stainfo(pstapriv, pattrib->src);
 534
 535        pwrbit = GetPwrMgt(ptr);
 536
 537        if (psta) {
 538                if (pwrbit) {
 539                        if (!(psta->state & WIFI_SLEEP_STATE))
 540                                stop_sta_xmit(padapter, psta);
 541                } else {
 542                        if (psta->state & WIFI_SLEEP_STATE)
 543                                wakeup_sta_to_xmit(padapter, psta);
 544                }
 545        }
 546
 547#endif
 548}
 549
 550static void process_wmmps_data(struct adapter *padapter, struct recv_frame *precv_frame)
 551{
 552#ifdef CONFIG_88EU_AP_MODE
 553        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 554        struct sta_priv *pstapriv = &padapter->stapriv;
 555        struct sta_info *psta = NULL;
 556
 557        psta = rtw_get_stainfo(pstapriv, pattrib->src);
 558
 559        if (!psta)
 560                return;
 561
 562        if (!psta->qos_option)
 563                return;
 564
 565        if (!(psta->qos_info & 0xf))
 566                return;
 567
 568        if (psta->state & WIFI_SLEEP_STATE) {
 569                u8 wmmps_ac = 0;
 570
 571                switch (pattrib->priority) {
 572                case 1:
 573                case 2:
 574                        wmmps_ac = psta->uapsd_bk & BIT(1);
 575                        break;
 576                case 4:
 577                case 5:
 578                        wmmps_ac = psta->uapsd_vi & BIT(1);
 579                        break;
 580                case 6:
 581                case 7:
 582                        wmmps_ac = psta->uapsd_vo & BIT(1);
 583                        break;
 584                case 0:
 585                case 3:
 586                default:
 587                        wmmps_ac = psta->uapsd_be & BIT(1);
 588                        break;
 589                }
 590
 591                if (wmmps_ac) {
 592                        if (psta->sleepq_ac_len > 0) {
 593                                /* process received triggered frame */
 594                                xmit_delivery_enabled_frames(padapter, psta);
 595                        } else {
 596                                /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */
 597                                issue_qos_nulldata(padapter, psta->hwaddr, (u16)pattrib->priority, 0, 0);
 598                        }
 599                }
 600        }
 601
 602#endif
 603}
 604
 605static void count_rx_stats(struct adapter *padapter, struct recv_frame *prframe, struct sta_info *sta)
 606{
 607        int     sz;
 608        struct sta_info         *psta = NULL;
 609        struct stainfo_stats    *pstats = NULL;
 610        struct rx_pkt_attrib    *pattrib = &prframe->attrib;
 611        struct recv_priv        *precvpriv = &padapter->recvpriv;
 612
 613        sz = get_recvframe_len(prframe);
 614        precvpriv->rx_bytes += sz;
 615
 616        padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
 617
 618        if (!is_broadcast_ether_addr(pattrib->dst) && !is_multicast_ether_addr(pattrib->dst))
 619                padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
 620
 621        if (sta)
 622                psta = sta;
 623        else
 624                psta = prframe->psta;
 625
 626        if (psta) {
 627                pstats = &psta->sta_stats;
 628
 629                pstats->rx_data_pkts++;
 630                pstats->rx_bytes += sz;
 631        }
 632}
 633
 634int sta2sta_data_frame(
 635        struct adapter *adapter,
 636        struct recv_frame *precv_frame,
 637        struct sta_info **psta
 638);
 639
 640int sta2sta_data_frame(struct adapter *adapter, struct recv_frame *precv_frame, struct sta_info **psta)
 641{
 642        u8 *ptr = precv_frame->rx_data;
 643        int ret = _SUCCESS;
 644        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 645        struct  sta_priv *pstapriv = &adapter->stapriv;
 646        struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
 647        u8 *mybssid  = get_bssid(pmlmepriv);
 648        u8 *myhwaddr = myid(&adapter->eeprompriv);
 649        u8 *sta_addr = NULL;
 650        bool bmcast = is_multicast_ether_addr(pattrib->dst);
 651
 652        if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 653            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 654                /*  filter packets that SA is myself or multicast or broadcast */
 655                if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
 656                        ret = _FAIL;
 657                        goto exit;
 658                }
 659
 660                if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
 661                        ret = _FAIL;
 662                        goto exit;
 663                }
 664
 665                if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
 666                    !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
 667                    memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
 668                        ret = _FAIL;
 669                        goto exit;
 670                }
 671
 672                sta_addr = pattrib->src;
 673        } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 674                /*  For Station mode, sa and bssid should always be BSSID, and DA is my mac-address */
 675                if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN)) {
 676                        ret = _FAIL;
 677                        goto exit;
 678                }
 679                sta_addr = pattrib->bssid;
 680        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 681                if (bmcast) {
 682                        /*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
 683                        if (!is_multicast_ether_addr(pattrib->bssid)) {
 684                                        ret = _FAIL;
 685                                        goto exit;
 686                        }
 687                } else { /*  not mc-frame */
 688                        /*  For AP mode, if DA is non-MCAST, then it must be BSSID, and bssid == BSSID */
 689                        if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN)) {
 690                                ret = _FAIL;
 691                                goto exit;
 692                        }
 693
 694                        sta_addr = pattrib->src;
 695                }
 696        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 697                memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
 698                memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
 699                memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
 700                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 701                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 702
 703                sta_addr = mybssid;
 704        } else {
 705                ret  = _FAIL;
 706        }
 707
 708        if (bmcast)
 709                *psta = rtw_get_bcmc_stainfo(adapter);
 710        else
 711                *psta = rtw_get_stainfo(pstapriv, sta_addr); /*  get ap_info */
 712
 713        if (!*psta) {
 714                if (adapter->registrypriv.mp_mode == 1) {
 715                        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 716                                adapter->mppriv.rx_pktloss++;
 717                }
 718                ret = _FAIL;
 719                goto exit;
 720        }
 721
 722exit:
 723
 724        return ret;
 725}
 726
 727static int ap2sta_data_frame(
 728        struct adapter *adapter,
 729        struct recv_frame *precv_frame,
 730        struct sta_info **psta)
 731{
 732        u8 *ptr = precv_frame->rx_data;
 733        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 734        int ret = _SUCCESS;
 735        struct  sta_priv *pstapriv = &adapter->stapriv;
 736        struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
 737        u8 *mybssid  = get_bssid(pmlmepriv);
 738        u8 *myhwaddr = myid(&adapter->eeprompriv);
 739        bool bmcast = is_multicast_ether_addr(pattrib->dst);
 740
 741        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
 742            (check_fwstate(pmlmepriv, _FW_LINKED) ||
 743             check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) {
 744                /*  filter packets that SA is myself or multicast or broadcast */
 745                if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN)) {
 746                        ret = _FAIL;
 747                        goto exit;
 748                }
 749
 750                /*  da should be for me */
 751                if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast)) {
 752                        ret = _FAIL;
 753                        goto exit;
 754                }
 755
 756                /*  check BSSID */
 757                if (!memcmp(pattrib->bssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
 758                    !memcmp(mybssid, "\x0\x0\x0\x0\x0\x0", ETH_ALEN) ||
 759                     (memcmp(pattrib->bssid, mybssid, ETH_ALEN))) {
 760                        if (!bmcast) {
 761                                DBG_88E("issue_deauth to the nonassociated ap=%pM for the reason(7)\n", (pattrib->bssid));
 762                                issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 763                        }
 764
 765                        ret = _FAIL;
 766                        goto exit;
 767                }
 768
 769                if (bmcast)
 770                        *psta = rtw_get_bcmc_stainfo(adapter);
 771                else
 772                        *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get ap_info */
 773
 774                if (!*psta) {
 775                        ret = _FAIL;
 776                        goto exit;
 777                }
 778
 779                /* if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) { */
 780                /*  */
 781
 782                if (GetFrameSubType(ptr) & BIT(6)) {
 783                        /* No data, will not indicate to upper layer, temporily count it here */
 784                        count_rx_stats(adapter, precv_frame, *psta);
 785                        ret = RTW_RX_HANDLED;
 786                        goto exit;
 787                }
 788        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
 789                   check_fwstate(pmlmepriv, _FW_LINKED)) {
 790                memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
 791                memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
 792                memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
 793                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 794                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 795
 796                /*  */
 797                memcpy(pattrib->bssid,  mybssid, ETH_ALEN);
 798
 799                *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
 800                if (!*psta) {
 801                        ret = _FAIL;
 802                        goto exit;
 803                }
 804        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 805                /* Special case */
 806                ret = RTW_RX_HANDLED;
 807                goto exit;
 808        } else {
 809                if (!memcmp(myhwaddr, pattrib->dst, ETH_ALEN) && (!bmcast)) {
 810                        *psta = rtw_get_stainfo(pstapriv, pattrib->bssid); /*  get sta_info */
 811                        if (!*psta) {
 812                                DBG_88E("issue_deauth to the ap =%pM for the reason(7)\n", (pattrib->bssid));
 813
 814                                issue_deauth(adapter, pattrib->bssid, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 815                        }
 816                }
 817
 818                ret = _FAIL;
 819        }
 820
 821exit:
 822
 823        return ret;
 824}
 825
 826static int sta2ap_data_frame(struct adapter *adapter,
 827                             struct recv_frame *precv_frame,
 828                             struct sta_info **psta)
 829{
 830        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 831        struct  sta_priv *pstapriv = &adapter->stapriv;
 832        struct  mlme_priv *pmlmepriv = &adapter->mlmepriv;
 833        u8 *ptr = precv_frame->rx_data;
 834        unsigned char *mybssid  = get_bssid(pmlmepriv);
 835        int ret = _SUCCESS;
 836
 837        if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 838                /* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */
 839                if (memcmp(pattrib->bssid, mybssid, ETH_ALEN)) {
 840                        ret = _FAIL;
 841                        goto exit;
 842                }
 843
 844                *psta = rtw_get_stainfo(pstapriv, pattrib->src);
 845                if (!*psta) {
 846                        DBG_88E("issue_deauth to sta=%pM for the reason(7)\n", (pattrib->src));
 847
 848                        issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 849
 850                        ret = RTW_RX_HANDLED;
 851                        goto exit;
 852                }
 853
 854                process_pwrbit_data(adapter, precv_frame);
 855
 856                if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) == WIFI_QOS_DATA_TYPE) {
 857                        process_wmmps_data(adapter, precv_frame);
 858                }
 859
 860                if (GetFrameSubType(ptr) & BIT(6)) {
 861                        /* No data, will not indicate to upper layer, temporily count it here */
 862                        count_rx_stats(adapter, precv_frame, *psta);
 863                        ret = RTW_RX_HANDLED;
 864                        goto exit;
 865                }
 866        } else {
 867                u8 *myhwaddr = myid(&adapter->eeprompriv);
 868                if (memcmp(pattrib->ra, myhwaddr, ETH_ALEN)) {
 869                        ret = RTW_RX_HANDLED;
 870                        goto exit;
 871                }
 872                DBG_88E("issue_deauth to sta=%pM for the reason(7)\n", (pattrib->src));
 873                issue_deauth(adapter, pattrib->src, WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 874                ret = RTW_RX_HANDLED;
 875                goto exit;
 876        }
 877
 878exit:
 879
 880        return ret;
 881}
 882
 883static int validate_recv_ctrl_frame(struct adapter *padapter,
 884                                    struct recv_frame *precv_frame)
 885{
 886#ifdef CONFIG_88EU_AP_MODE
 887        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 888        struct sta_priv *pstapriv = &padapter->stapriv;
 889        u8 *pframe = precv_frame->rx_data;
 890        /* uint len = precv_frame->len; */
 891
 892        if (GetFrameType(pframe) != WIFI_CTRL_TYPE)
 893                return _FAIL;
 894
 895        /* receive the frames that ra(a1) is my address */
 896        if (memcmp(GetAddr1Ptr(pframe), myid(&padapter->eeprompriv), ETH_ALEN))
 897                return _FAIL;
 898
 899        /* only handle ps-poll */
 900        if (GetFrameSubType(pframe) == WIFI_PSPOLL) {
 901                u16 aid;
 902                u8 wmmps_ac = 0;
 903                struct sta_info *psta = NULL;
 904
 905                aid = GetAid(pframe);
 906                psta = rtw_get_stainfo(pstapriv, GetAddr2Ptr(pframe));
 907
 908                if (!psta || psta->aid != aid)
 909                        return _FAIL;
 910
 911                /* for rx pkt statistics */
 912                psta->sta_stats.rx_ctrl_pkts++;
 913
 914                switch (pattrib->priority) {
 915                case 1:
 916                case 2:
 917                        wmmps_ac = psta->uapsd_bk & BIT(0);
 918                        break;
 919                case 4:
 920                case 5:
 921                        wmmps_ac = psta->uapsd_vi & BIT(0);
 922                        break;
 923                case 6:
 924                case 7:
 925                        wmmps_ac = psta->uapsd_vo & BIT(0);
 926                        break;
 927                case 0:
 928                case 3:
 929                default:
 930                        wmmps_ac = psta->uapsd_be & BIT(0);
 931                        break;
 932                }
 933
 934                if (wmmps_ac)
 935                        return _FAIL;
 936
 937                if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
 938                        DBG_88E("%s alive check-rx ps-poll\n", __func__);
 939                        psta->expire_to = pstapriv->expire_to;
 940                        psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
 941                }
 942
 943                if ((psta->state & WIFI_SLEEP_STATE) && (pstapriv->sta_dz_bitmap & BIT(psta->aid))) {
 944                        struct list_head *xmitframe_plist, *xmitframe_phead;
 945                        struct xmit_frame *pxmitframe = NULL;
 946                        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 947
 948                        spin_lock_bh(&pxmitpriv->lock);
 949
 950                        xmitframe_phead = get_list_head(&psta->sleep_q);
 951                        xmitframe_plist = xmitframe_phead->next;
 952
 953                        if (xmitframe_phead != xmitframe_plist) {
 954                                pxmitframe = container_of(xmitframe_plist, struct xmit_frame, list);
 955
 956                                xmitframe_plist = xmitframe_plist->next;
 957
 958                                list_del_init(&pxmitframe->list);
 959
 960                                psta->sleepq_len--;
 961
 962                                if (psta->sleepq_len > 0)
 963                                        pxmitframe->attrib.mdata = 1;
 964                                else
 965                                        pxmitframe->attrib.mdata = 0;
 966
 967                                pxmitframe->attrib.triggered = 1;
 968
 969                                rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
 970
 971                                if (psta->sleepq_len == 0) {
 972                                        pstapriv->tim_bitmap &= ~BIT(psta->aid);
 973
 974                                        /* upate BCN for TIM IE */
 975                                        /* update_BCNTIM(padapter); */
 976                                        update_beacon(padapter, _TIM_IE_, NULL, false);
 977                                }
 978                        } else {
 979                                if (pstapriv->tim_bitmap & BIT(psta->aid)) {
 980                                        if (psta->sleepq_len == 0) {
 981                                                DBG_88E("no buffered packets to xmit\n");
 982
 983                                                /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
 984                                                issue_nulldata(padapter, psta->hwaddr, 0, 0, 0);
 985                                        } else {
 986                                                DBG_88E("error!psta->sleepq_len=%d\n", psta->sleepq_len);
 987                                                psta->sleepq_len = 0;
 988                                        }
 989
 990                                        pstapriv->tim_bitmap &= ~BIT(psta->aid);
 991
 992                                        /* upate BCN for TIM IE */
 993                                        /* update_BCNTIM(padapter); */
 994                                        update_beacon(padapter, _TIM_IE_, NULL, false);
 995                                }
 996                        }
 997                        spin_unlock_bh(&pxmitpriv->lock);
 998                }
 999        }
1000
1001#endif
1002
1003        return _FAIL;
1004}
1005
1006struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame);
1007
1008static int validate_recv_mgnt_frame(struct adapter *padapter,
1009                                    struct recv_frame *precv_frame)
1010{
1011        struct sta_info *psta;
1012
1013        precv_frame = recvframe_chk_defrag(padapter, precv_frame);
1014        if (!precv_frame)
1015                return _SUCCESS;
1016
1017        /* for rx pkt statistics */
1018        psta = rtw_get_stainfo(&padapter->stapriv, GetAddr2Ptr(precv_frame->rx_data));
1019        if (psta) {
1020                psta->sta_stats.rx_mgnt_pkts++;
1021                if (GetFrameSubType(precv_frame->rx_data) == WIFI_BEACON) {
1022                        psta->sta_stats.rx_beacon_pkts++;
1023                } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBEREQ) {
1024                        psta->sta_stats.rx_probereq_pkts++;
1025                } else if (GetFrameSubType(precv_frame->rx_data) == WIFI_PROBERSP) {
1026                        if (!memcmp(padapter->eeprompriv.mac_addr, GetAddr1Ptr(precv_frame->rx_data), ETH_ALEN))
1027                                psta->sta_stats.rx_probersp_pkts++;
1028                        else if (is_broadcast_mac_addr(GetAddr1Ptr(precv_frame->rx_data)) ||
1029                                 is_multicast_mac_addr(GetAddr1Ptr(precv_frame->rx_data)))
1030                                psta->sta_stats.rx_probersp_bm_pkts++;
1031                        else
1032                                psta->sta_stats.rx_probersp_uo_pkts++;
1033                }
1034        }
1035
1036        mgt_dispatcher(padapter, precv_frame);
1037
1038        return _SUCCESS;
1039}
1040
1041static int validate_recv_data_frame(struct adapter *adapter,
1042                                    struct recv_frame *precv_frame)
1043{
1044        u8 bretry;
1045        u8 *psa, *pda, *pbssid;
1046        struct sta_info *psta = NULL;
1047        u8 *ptr = precv_frame->rx_data;
1048        struct rx_pkt_attrib    *pattrib = &precv_frame->attrib;
1049        struct security_priv    *psecuritypriv = &adapter->securitypriv;
1050        int ret = _SUCCESS;
1051
1052        bretry = GetRetry(ptr);
1053        pda = get_da(ptr);
1054        psa = get_sa(ptr);
1055        pbssid = get_hdr_bssid(ptr);
1056
1057        if (!pbssid) {
1058                ret = _FAIL;
1059                goto exit;
1060        }
1061
1062        memcpy(pattrib->dst, pda, ETH_ALEN);
1063        memcpy(pattrib->src, psa, ETH_ALEN);
1064
1065        memcpy(pattrib->bssid, pbssid, ETH_ALEN);
1066
1067        switch (pattrib->to_fr_ds) {
1068        case 0:
1069                memcpy(pattrib->ra, pda, ETH_ALEN);
1070                memcpy(pattrib->ta, psa, ETH_ALEN);
1071                ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1072                break;
1073        case 1:
1074                memcpy(pattrib->ra, pda, ETH_ALEN);
1075                memcpy(pattrib->ta, pbssid, ETH_ALEN);
1076                ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1077                break;
1078        case 2:
1079                memcpy(pattrib->ra, pbssid, ETH_ALEN);
1080                memcpy(pattrib->ta, psa, ETH_ALEN);
1081                ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1082                break;
1083        case 3:
1084                memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
1085                memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
1086                ret = _FAIL;
1087                break;
1088        default:
1089                ret = _FAIL;
1090                break;
1091        }
1092
1093        if (ret == _FAIL) {
1094                goto exit;
1095        } else if (ret == RTW_RX_HANDLED) {
1096                goto exit;
1097        }
1098
1099        if (!psta) {
1100                ret = _FAIL;
1101                goto exit;
1102        }
1103
1104        /* psta->rssi = prxcmd->rssi; */
1105        /* psta->signal_quality = prxcmd->sq; */
1106        precv_frame->psta = psta;
1107
1108        pattrib->amsdu = 0;
1109        pattrib->ack_policy = 0;
1110        /* parsing QC field */
1111        if (pattrib->qos == 1) {
1112                pattrib->priority = GetPriority((ptr + 24));
1113                pattrib->ack_policy = GetAckpolicy((ptr + 24));
1114                pattrib->amsdu = GetAMsdu((ptr + 24));
1115                pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
1116
1117                if (pattrib->priority != 0 && pattrib->priority != 3)
1118                        adapter->recvpriv.bIsAnyNonBEPkts = true;
1119        } else {
1120                pattrib->priority = 0;
1121                pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 30 : 24;
1122        }
1123
1124        if (pattrib->order)/* HT-CTRL 11n */
1125                pattrib->hdrlen += 4;
1126
1127        precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1128
1129        /*  decache, drop duplicate recv packets */
1130        if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) == _FAIL) {
1131                ret = _FAIL;
1132                goto exit;
1133        }
1134
1135        if (pattrib->privacy) {
1136                GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, is_multicast_ether_addr(pattrib->ra));
1137
1138                SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len, pattrib->encrypt);
1139        } else {
1140                pattrib->encrypt = 0;
1141                pattrib->iv_len = 0;
1142                pattrib->icv_len = 0;
1143        }
1144
1145exit:
1146
1147        return ret;
1148}
1149
1150static int validate_recv_frame(struct adapter *adapter, struct recv_frame *precv_frame)
1151{
1152        /* shall check frame subtype, to / from ds, da, bssid */
1153
1154        /* then call check if rx seq/frag. duplicated. */
1155
1156        u8 type;
1157        u8 subtype;
1158        int retval = _SUCCESS;
1159        u8 bDumpRxPkt;
1160        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
1161        u8 *ptr = precv_frame->rx_data;
1162        u8  ver = (unsigned char)(*ptr) & 0x3;
1163        struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
1164
1165        if (pmlmeext->sitesurvey_res.state == SCAN_PROCESS) {
1166                int ch_set_idx = rtw_ch_set_search_ch(pmlmeext->channel_set, rtw_get_oper_ch(adapter));
1167                if (ch_set_idx >= 0)
1168                        pmlmeext->channel_set[ch_set_idx].rx_count++;
1169        }
1170
1171        /* add version chk */
1172        if (ver != 0) {
1173                retval = _FAIL;
1174                goto exit;
1175        }
1176
1177        type =  GetFrameType(ptr);
1178        subtype = GetFrameSubType(ptr); /* bit(7)~bit(2) */
1179
1180        pattrib->to_fr_ds = get_tofr_ds(ptr);
1181
1182        pattrib->frag_num = GetFragNum(ptr);
1183        pattrib->seq_num = GetSequence(ptr);
1184
1185        pattrib->pw_save = GetPwrMgt(ptr);
1186        pattrib->mfrag = GetMFrag(ptr);
1187        pattrib->mdata = GetMData(ptr);
1188        pattrib->privacy = GetPrivacy(ptr);
1189        pattrib->order = GetOrder(ptr);
1190
1191        /* Dump rx packets */
1192        rtw_hal_get_def_var(adapter, HAL_DEF_DBG_DUMP_RXPKT, &(bDumpRxPkt));
1193        if (bDumpRxPkt == 1) {/* dump all rx packets */
1194                int i;
1195                DBG_88E("#############################\n");
1196
1197                for (i = 0; i < 64; i = i + 8)
1198                        DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
1199                                *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
1200                DBG_88E("#############################\n");
1201        } else if (bDumpRxPkt == 2) {
1202                if (type == WIFI_MGT_TYPE) {
1203                        int i;
1204                        DBG_88E("#############################\n");
1205
1206                        for (i = 0; i < 64; i = i + 8)
1207                                DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
1208                                        *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
1209                        DBG_88E("#############################\n");
1210                }
1211        } else if (bDumpRxPkt == 3) {
1212                if (type == WIFI_DATA_TYPE) {
1213                        int i;
1214                        DBG_88E("#############################\n");
1215
1216                        for (i = 0; i < 64; i = i + 8)
1217                                DBG_88E("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n", *(ptr + i),
1218                                        *(ptr + i + 1), *(ptr + i + 2), *(ptr + i + 3), *(ptr + i + 4), *(ptr + i + 5), *(ptr + i + 6), *(ptr + i + 7));
1219                        DBG_88E("#############################\n");
1220                }
1221        }
1222        switch (type) {
1223        case WIFI_MGT_TYPE: /* mgnt */
1224                validate_recv_mgnt_frame(adapter, precv_frame);
1225                retval = _FAIL; /*  only data frame return _SUCCESS */
1226                break;
1227        case WIFI_CTRL_TYPE: /* ctrl */
1228                validate_recv_ctrl_frame(adapter, precv_frame);
1229                retval = _FAIL; /*  only data frame return _SUCCESS */
1230                break;
1231        case WIFI_DATA_TYPE: /* data */
1232                rtw_led_control(adapter, LED_CTL_RX);
1233                pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
1234                retval = validate_recv_data_frame(adapter, precv_frame);
1235                if (retval == _FAIL) {
1236                        struct recv_priv *precvpriv = &adapter->recvpriv;
1237                        precvpriv->rx_drop++;
1238                }
1239                break;
1240        default:
1241                retval = _FAIL;
1242                break;
1243        }
1244
1245exit:
1246
1247        return retval;
1248}
1249
1250/* remove the wlanhdr and add the eth_hdr */
1251
1252static int wlanhdr_to_ethhdr(struct recv_frame *precvframe)
1253{
1254        int     rmv_len;
1255        u16     eth_type, len;
1256        __be16 be_tmp;
1257        u8      bsnaphdr;
1258        u8      *psnap_type;
1259        struct ieee80211_snap_hdr       *psnap;
1260
1261        int ret = _SUCCESS;
1262        struct adapter                  *adapter = precvframe->adapter;
1263        struct mlme_priv        *pmlmepriv = &adapter->mlmepriv;
1264
1265        u8      *ptr = get_recvframe_data(precvframe); /*  point to frame_ctrl field */
1266        struct rx_pkt_attrib *pattrib = &precvframe->attrib;
1267
1268        if (pattrib->encrypt)
1269                recvframe_pull_tail(precvframe, pattrib->icv_len);
1270
1271        psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen + pattrib->iv_len);
1272        psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
1273        /* convert hdr + possible LLC headers into Ethernet header */
1274        if ((!memcmp(psnap, rtw_rfc1042_header, SNAP_SIZE) &&
1275             memcmp(psnap_type, SNAP_ETH_TYPE_IPX, 2) &&
1276            memcmp(psnap_type, SNAP_ETH_TYPE_APPLETALK_AARP, 2)) ||
1277            !memcmp(psnap, rtw_bridge_tunnel_header, SNAP_SIZE)) {
1278                /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
1279                bsnaphdr = true;
1280        } else {
1281                /* Leave Ethernet header part of hdr and full payload */
1282                bsnaphdr = false;
1283        }
1284
1285        rmv_len = pattrib->hdrlen + pattrib->iv_len + (bsnaphdr ? SNAP_SIZE : 0);
1286        len = precvframe->len - rmv_len;
1287
1288        memcpy(&be_tmp, ptr + rmv_len, 2);
1289        eth_type = ntohs(be_tmp); /* pattrib->ether_type */
1290        pattrib->eth_type = eth_type;
1291
1292        if ((check_fwstate(pmlmepriv, WIFI_MP_STATE))) {
1293                ptr += rmv_len;
1294                *ptr = 0x87;
1295                *(ptr + 1) = 0x12;
1296
1297                eth_type = 0x8712;
1298                /*  append rx status for mp test packets */
1299                ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + 2) - 24);
1300                memcpy(ptr, get_rxmem(precvframe), 24);
1301                ptr += 24;
1302        } else {
1303                ptr = recvframe_pull(precvframe, (rmv_len - sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
1304        }
1305
1306        memcpy(ptr, pattrib->dst, ETH_ALEN);
1307        memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
1308
1309        if (!bsnaphdr) {
1310                be_tmp = htons(len);
1311                memcpy(ptr + 12, &be_tmp, 2);
1312        }
1313
1314        return ret;
1315}
1316
1317/* perform defrag */
1318static struct recv_frame *recvframe_defrag(struct adapter *adapter, struct __queue *defrag_q)
1319{
1320        struct list_head *plist, *phead;
1321        u8 wlanhdr_offset;
1322        u8      curfragnum;
1323        struct recv_frame *pfhdr, *pnfhdr;
1324        struct recv_frame *prframe, *pnextrframe;
1325        struct __queue *pfree_recv_queue;
1326
1327        curfragnum = 0;
1328        pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
1329
1330        phead = get_list_head(defrag_q);
1331        plist = phead->next;
1332        pfhdr = container_of(plist, struct recv_frame, list);
1333        prframe = (struct recv_frame *)pfhdr;
1334        list_del_init(&prframe->list);
1335
1336        if (curfragnum != pfhdr->attrib.frag_num) {
1337                /* the first fragment number must be 0 */
1338                /* free the whole queue */
1339                rtw_free_recvframe(prframe, pfree_recv_queue);
1340                rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1341
1342                return NULL;
1343        }
1344
1345        curfragnum++;
1346
1347        plist = get_list_head(defrag_q);
1348        plist = phead->next;
1349        pfhdr = container_of(plist, struct recv_frame, list);
1350        prframe = (struct recv_frame *)pfhdr;
1351        list_del_init(&prframe->list);
1352
1353        plist = plist->next;
1354
1355        while (phead != plist) {
1356                pnfhdr = container_of(plist, struct recv_frame, list);
1357                pnextrframe = (struct recv_frame *)pnfhdr;
1358
1359                /* check the fragment sequence  (2nd ~n fragment frame) */
1360
1361                if (curfragnum != pnfhdr->attrib.frag_num) {
1362                        /* the fragment number must be increasing  (after decache) */
1363                        /* release the defrag_q & prframe */
1364                        rtw_free_recvframe(prframe, pfree_recv_queue);
1365                        rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1366                        return NULL;
1367                }
1368
1369                curfragnum++;
1370
1371                /* copy the 2nd~n fragment frame's payload to the first fragment */
1372                /* get the 2nd~last fragment frame's payload */
1373
1374                wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1375
1376                recvframe_pull(pnextrframe, wlanhdr_offset);
1377
1378                /* append  to first fragment frame's tail (if privacy frame, pull the ICV) */
1379                recvframe_pull_tail(prframe, pfhdr->attrib.icv_len);
1380
1381                /* memcpy */
1382                memcpy(pfhdr->rx_tail, pnfhdr->rx_data, pnfhdr->len);
1383
1384                recvframe_put(prframe, pnfhdr->len);
1385
1386                pfhdr->attrib.icv_len = pnfhdr->attrib.icv_len;
1387                plist = plist->next;
1388        }
1389
1390        /* free the defrag_q queue and return the prframe */
1391        rtw_free_recvframe_queue(defrag_q, pfree_recv_queue);
1392
1393        return prframe;
1394}
1395
1396/* check if need to defrag, if needed queue the frame to defrag_q */
1397struct recv_frame *recvframe_chk_defrag(struct adapter *padapter, struct recv_frame *precv_frame)
1398{
1399        u8      ismfrag;
1400        u8      fragnum;
1401        u8      *psta_addr;
1402        struct recv_frame *pfhdr;
1403        struct sta_info *psta;
1404        struct sta_priv *pstapriv;
1405        struct list_head *phead;
1406        struct recv_frame *prtnframe = NULL;
1407        struct __queue *pfree_recv_queue, *pdefrag_q;
1408
1409        pstapriv = &padapter->stapriv;
1410
1411        pfhdr = precv_frame;
1412
1413        pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1414
1415        /* need to define struct of wlan header frame ctrl */
1416        ismfrag = pfhdr->attrib.mfrag;
1417        fragnum = pfhdr->attrib.frag_num;
1418
1419        psta_addr = pfhdr->attrib.ta;
1420        psta = rtw_get_stainfo(pstapriv, psta_addr);
1421        if (!psta) {
1422                u8 type = GetFrameType(pfhdr->rx_data);
1423                if (type != WIFI_DATA_TYPE) {
1424                        psta = rtw_get_bcmc_stainfo(padapter);
1425                        pdefrag_q = &psta->sta_recvpriv.defrag_q;
1426                } else {
1427                        pdefrag_q = NULL;
1428                }
1429        } else {
1430                pdefrag_q = &psta->sta_recvpriv.defrag_q;
1431        }
1432
1433        if ((ismfrag == 0) && (fragnum == 0))
1434                prtnframe = precv_frame;/* isn't a fragment frame */
1435
1436        if (ismfrag == 1) {
1437                /* 0~(n-1) fragment frame */
1438                /* enqueue to defraf_g */
1439                if (pdefrag_q) {
1440                        if (fragnum == 0) {
1441                                /* the first fragment */
1442                                if (!list_empty(&pdefrag_q->queue)) {
1443                                        /* free current defrag_q */
1444                                        rtw_free_recvframe_queue(pdefrag_q, pfree_recv_queue);
1445                                }
1446                        }
1447
1448                        /* Then enqueue the 0~(n-1) fragment into the defrag_q */
1449
1450                        phead = get_list_head(pdefrag_q);
1451                        list_add_tail(&pfhdr->list, phead);
1452
1453                        prtnframe = NULL;
1454                } else {
1455                        /* can't find this ta's defrag_queue, so free this recv_frame */
1456                        if (precv_frame && pfree_recv_queue)
1457                                rtw_free_recvframe(precv_frame, pfree_recv_queue);
1458                        prtnframe = NULL;
1459                }
1460        }
1461
1462        if ((ismfrag == 0) && (fragnum != 0)) {
1463                /* the last fragment frame */
1464                /* enqueue the last fragment */
1465                if (pdefrag_q) {
1466                        phead = get_list_head(pdefrag_q);
1467                        list_add_tail(&pfhdr->list, phead);
1468
1469                        /* call recvframe_defrag to defrag */
1470                        precv_frame = recvframe_defrag(padapter, pdefrag_q);
1471                        prtnframe = precv_frame;
1472                } else {
1473                        /* can't find this ta's defrag_queue, so free this recv_frame */
1474                        if (precv_frame && pfree_recv_queue)
1475                                rtw_free_recvframe(precv_frame, pfree_recv_queue);
1476                        prtnframe = NULL;
1477                }
1478        }
1479
1480        if (prtnframe && prtnframe->attrib.privacy) {
1481                /* after defrag we must check tkip mic code */
1482                if (recvframe_chkmic(padapter,  prtnframe) == _FAIL) {
1483                        if (precv_frame && pfree_recv_queue)
1484                                rtw_free_recvframe(prtnframe, pfree_recv_queue);
1485                        prtnframe = NULL;
1486                }
1487        }
1488
1489        return prtnframe;
1490}
1491
1492static int amsdu_to_msdu(struct adapter *padapter, struct recv_frame *prframe)
1493{
1494        int     a_len, padding_len;
1495        u16     eth_type, nSubframe_Length;
1496        u8      nr_subframes, i;
1497        unsigned char *pdata;
1498        struct rx_pkt_attrib *pattrib;
1499        unsigned char *data_ptr;
1500        struct sk_buff *sub_skb, *subframes[MAX_SUBFRAME_COUNT];
1501        struct recv_priv *precvpriv = &padapter->recvpriv;
1502        struct __queue *pfree_recv_queue = &precvpriv->free_recv_queue;
1503        int     ret = _SUCCESS;
1504        nr_subframes = 0;
1505
1506        pattrib = &prframe->attrib;
1507
1508        recvframe_pull(prframe, prframe->attrib.hdrlen);
1509
1510        if (prframe->attrib.iv_len > 0)
1511                recvframe_pull(prframe, prframe->attrib.iv_len);
1512
1513        a_len = prframe->len;
1514
1515        pdata = prframe->rx_data;
1516
1517        while (a_len > ETH_HLEN) {
1518                /* Offset 12 denote 2 mac address */
1519                nSubframe_Length = RTW_GET_BE16(pdata + 12);
1520
1521                if (a_len < ETH_HLEN + nSubframe_Length) {
1522                        DBG_88E("nRemain_Length is %d and nSubframe_Length is : %d\n", a_len, nSubframe_Length);
1523                        goto exit;
1524                }
1525
1526                /* move the data point to data content */
1527                pdata += ETH_HLEN;
1528                a_len -= ETH_HLEN;
1529
1530                /* Allocate new skb for releasing to upper layer */
1531                sub_skb = dev_alloc_skb(nSubframe_Length + 12);
1532                if (sub_skb) {
1533                        skb_reserve(sub_skb, 12);
1534                        data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length);
1535                        memcpy(data_ptr, pdata, nSubframe_Length);
1536                } else {
1537                        sub_skb = skb_clone(prframe->pkt, GFP_ATOMIC);
1538                        if (sub_skb) {
1539                                sub_skb->data = pdata;
1540                                sub_skb->len = nSubframe_Length;
1541                                skb_set_tail_pointer(sub_skb, nSubframe_Length);
1542                        } else {
1543                                DBG_88E("skb_clone() Fail!!! , nr_subframes=%d\n", nr_subframes);
1544                                break;
1545                        }
1546                }
1547
1548                subframes[nr_subframes++] = sub_skb;
1549
1550                if (nr_subframes >= MAX_SUBFRAME_COUNT) {
1551                        DBG_88E("ParseSubframe(): Too many Subframes! Packets dropped!\n");
1552                        break;
1553                }
1554
1555                pdata += nSubframe_Length;
1556                a_len -= nSubframe_Length;
1557                if (a_len != 0) {
1558                        padding_len = 4 - ((nSubframe_Length + ETH_HLEN) & (4 - 1));
1559                        if (padding_len == 4) {
1560                                padding_len = 0;
1561                        }
1562
1563                        if (a_len < padding_len) {
1564                                goto exit;
1565                        }
1566                        pdata += padding_len;
1567                        a_len -= padding_len;
1568                }
1569        }
1570
1571        for (i = 0; i < nr_subframes; i++) {
1572                sub_skb = subframes[i];
1573                /* convert hdr + possible LLC headers into Ethernet header */
1574                eth_type = RTW_GET_BE16(&sub_skb->data[6]);
1575                if (sub_skb->len >= 8 &&
1576                    ((!memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE) &&
1577                          eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
1578                         !memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE))) {
1579                        /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
1580                        skb_pull(sub_skb, SNAP_SIZE);
1581                        memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
1582                        memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
1583                } else {
1584                        __be16 len;
1585                        /* Leave Ethernet header part of hdr and full payload */
1586                        len = htons(sub_skb->len);
1587                        memcpy(skb_push(sub_skb, 2), &len, 2);
1588                        memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
1589                        memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
1590                }
1591
1592                /* Indicate the packets to upper layer */
1593                        /*  Insert NAT2.5 RX here! */
1594                sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
1595                sub_skb->dev = padapter->pnetdev;
1596
1597                sub_skb->ip_summed = CHECKSUM_NONE;
1598
1599                netif_rx(sub_skb);
1600        }
1601
1602exit:
1603
1604        prframe->len = 0;
1605        rtw_free_recvframe(prframe, pfree_recv_queue);/* free this recv_frame */
1606
1607        return ret;
1608}
1609
1610static int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
1611{
1612        u8      wsize = preorder_ctrl->wsize_b;
1613        u16     wend = (preorder_ctrl->indicate_seq + wsize - 1) & 0xFFF;/*  4096; */
1614
1615        /*  Rx Reorder initialize condition. */
1616        if (preorder_ctrl->indicate_seq == 0xFFFF)
1617                preorder_ctrl->indicate_seq = seq_num;
1618
1619        /*  Drop out the packet which SeqNum is smaller than WinStart */
1620        if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
1621                return false;
1622
1623        /*  */
1624        /*  Sliding window manipulation. Conditions includes: */
1625        /*  1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
1626        /*  2. Incoming SeqNum is larger than the WinEnd => Window shift N */
1627        /*  */
1628        if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
1629                preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
1630        } else if (SN_LESS(wend, seq_num)) {
1631                if (seq_num >= (wsize - 1))
1632                        preorder_ctrl->indicate_seq = seq_num + 1 - wsize;
1633                else
1634                        preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
1635        }
1636
1637        return true;
1638}
1639
1640int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe);
1641int enqueue_reorder_recvframe(struct recv_reorder_ctrl *preorder_ctrl, struct recv_frame *prframe)
1642{
1643        struct rx_pkt_attrib *pattrib = &prframe->attrib;
1644        struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1645        struct list_head *phead, *plist;
1646        struct recv_frame *hdr;
1647        struct rx_pkt_attrib *pnextattrib;
1648
1649        phead = get_list_head(ppending_recvframe_queue);
1650        plist = phead->next;
1651
1652        while (phead != plist) {
1653                hdr = container_of(plist, struct recv_frame, list);
1654                pnextattrib = &hdr->attrib;
1655
1656                if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num))
1657                        plist = plist->next;
1658                else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num))
1659                        return false;
1660                else
1661                        break;
1662        }
1663
1664        list_del_init(&prframe->list);
1665
1666        list_add_tail(&prframe->list, plist);
1667        return true;
1668}
1669
1670static int recv_indicatepkts_in_order(struct adapter *padapter, struct recv_reorder_ctrl *preorder_ctrl, int bforced)
1671{
1672        struct list_head *phead, *plist;
1673        struct recv_frame *prframe;
1674        struct rx_pkt_attrib *pattrib;
1675        int bPktInBuf = false;
1676        struct recv_priv *precvpriv = &padapter->recvpriv;
1677        struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1678
1679        phead =         get_list_head(ppending_recvframe_queue);
1680        plist = phead->next;
1681
1682        /*  Handling some condition for forced indicate case. */
1683        if (bforced) {
1684                if (list_empty(phead))
1685                        return true;
1686
1687                prframe = container_of(plist, struct recv_frame, list);
1688                pattrib = &prframe->attrib;
1689                preorder_ctrl->indicate_seq = pattrib->seq_num;
1690        }
1691
1692        /*  Prepare indication list and indication. */
1693        /*  Check if there is any packet need indicate. */
1694        while (!list_empty(phead)) {
1695                prframe = container_of(plist, struct recv_frame, list);
1696                pattrib = &prframe->attrib;
1697
1698                if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
1699                        plist = plist->next;
1700                        list_del_init(&prframe->list);
1701
1702                        if (SN_EQUAL(preorder_ctrl->indicate_seq, pattrib->seq_num))
1703                                preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) & 0xFFF;
1704
1705                        /* Set this as a lock to make sure that only one thread is indicating packet. */
1706
1707                        /* indicate this recv_frame */
1708                        if (!pattrib->amsdu) {
1709                                if ((!padapter->bDriverStopped) &&
1710                                    (!padapter->bSurpriseRemoved))
1711                                        rtw_recv_indicatepkt(padapter, prframe);/* indicate this recv_frame */
1712                        } else if (pattrib->amsdu == 1) {
1713                                if (amsdu_to_msdu(padapter, prframe) != _SUCCESS)
1714                                        rtw_free_recvframe(prframe, &precvpriv->free_recv_queue);
1715                        } else {
1716                                /* error condition; */
1717                        }
1718
1719                        /* Update local variables. */
1720                        bPktInBuf = false;
1721                } else {
1722                        bPktInBuf = true;
1723                        break;
1724                }
1725        }
1726        return bPktInBuf;
1727}
1728
1729static int recv_indicatepkt_reorder(struct adapter *padapter, struct recv_frame *prframe)
1730{
1731        int retval = _SUCCESS;
1732        struct rx_pkt_attrib *pattrib = &prframe->attrib;
1733        struct recv_reorder_ctrl *preorder_ctrl = prframe->preorder_ctrl;
1734        struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1735
1736        if (!pattrib->amsdu) {
1737                /* s1. */
1738                wlanhdr_to_ethhdr(prframe);
1739
1740                if (pattrib->qos != 1) {
1741                        if (!padapter->bDriverStopped &&
1742                            !padapter->bSurpriseRemoved) {
1743                                rtw_recv_indicatepkt(padapter, prframe);
1744                                return _SUCCESS;
1745                        }
1746
1747                        return _FAIL;
1748                }
1749
1750                if (!preorder_ctrl->enable) {
1751                        /* indicate this recv_frame */
1752                        preorder_ctrl->indicate_seq = pattrib->seq_num;
1753                        rtw_recv_indicatepkt(padapter, prframe);
1754
1755                        preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096;
1756                        return _SUCCESS;
1757                }
1758        } else if (pattrib->amsdu == 1) { /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
1759                if (!preorder_ctrl->enable) {
1760                        preorder_ctrl->indicate_seq = pattrib->seq_num;
1761                        retval = amsdu_to_msdu(padapter, prframe);
1762
1763                        preorder_ctrl->indicate_seq = (preorder_ctrl->indicate_seq + 1) % 4096;
1764                        return retval;
1765                }
1766        }
1767
1768        spin_lock_bh(&ppending_recvframe_queue->lock);
1769
1770        /* s2. check if winstart_b(indicate_seq) needs to been updated */
1771        if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num))
1772                goto _err_exit;
1773
1774        /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
1775        if (!enqueue_reorder_recvframe(preorder_ctrl, prframe))
1776                goto _err_exit;
1777
1778        /* s4. */
1779        /*  Indication process. */
1780        /*  After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets */
1781        /*  with the SeqNum smaller than latest WinStart and buffer other packets. */
1782        /*  */
1783        /*  For Rx Reorder condition: */
1784        /*  1. All packets with SeqNum smaller than WinStart => Indicate */
1785        /*  2. All packets with SeqNum larger than or equal to WinStart => Buffer it. */
1786        /*  */
1787
1788        /* recv_indicatepkts_in_order(padapter, preorder_ctrl, true); */
1789        if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false)) {
1790                _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
1791                spin_unlock_bh(&ppending_recvframe_queue->lock);
1792        } else {
1793                spin_unlock_bh(&ppending_recvframe_queue->lock);
1794                _cancel_timer_ex(&preorder_ctrl->reordering_ctrl_timer);
1795        }
1796
1797        return _SUCCESS;
1798
1799_err_exit:
1800
1801        spin_unlock_bh(&ppending_recvframe_queue->lock);
1802
1803        return _FAIL;
1804}
1805
1806void rtw_reordering_ctrl_timeout_handler(void *pcontext)
1807{
1808        struct recv_reorder_ctrl *preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
1809        struct adapter *padapter = preorder_ctrl->padapter;
1810        struct __queue *ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1811
1812        if (padapter->bDriverStopped || padapter->bSurpriseRemoved)
1813                return;
1814
1815        spin_lock_bh(&ppending_recvframe_queue->lock);
1816
1817        if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true))
1818                _set_timer(&preorder_ctrl->reordering_ctrl_timer, REORDER_WAIT_TIME);
1819
1820        spin_unlock_bh(&ppending_recvframe_queue->lock);
1821}
1822
1823static int process_recv_indicatepkts(struct adapter *padapter, struct recv_frame *prframe)
1824{
1825        int retval = _SUCCESS;
1826        /* struct recv_priv *precvpriv = &padapter->recvpriv; */
1827        /* struct rx_pkt_attrib *pattrib = &prframe->attrib; */
1828        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
1829        struct ht_priv  *phtpriv = &pmlmepriv->htpriv;
1830
1831        if (phtpriv->ht_option) {  /* B/G/N Mode */
1832                /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
1833
1834                if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
1835                        /*  including perform A-MPDU Rx Ordering Buffer Control */
1836                        if ((!padapter->bDriverStopped) &&
1837                            (!padapter->bSurpriseRemoved)) {
1838                                retval = _FAIL;
1839                                return retval;
1840                        }
1841                }
1842        } else { /* B/G mode */
1843                retval = wlanhdr_to_ethhdr(prframe);
1844                if (retval != _SUCCESS)
1845                        return retval;
1846
1847                if ((!padapter->bDriverStopped) &&
1848                    (!padapter->bSurpriseRemoved)) {
1849                        /* indicate this recv_frame */
1850                        rtw_recv_indicatepkt(padapter, prframe);
1851                } else {
1852                        retval = _FAIL;
1853                        return retval;
1854                }
1855        }
1856
1857        return retval;
1858}
1859
1860static int recv_func_prehandle(struct adapter *padapter, struct recv_frame *rframe)
1861{
1862        int ret = _SUCCESS;
1863        struct rx_pkt_attrib *pattrib = &rframe->attrib;
1864        struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1865        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1866
1867        if (padapter->registrypriv.mp_mode == 1) {
1868                if (pattrib->crc_err == 1)
1869                        padapter->mppriv.rx_crcerrpktcount++;
1870                else
1871                        padapter->mppriv.rx_pktcount++;
1872
1873                if (!check_fwstate(pmlmepriv, WIFI_MP_LPBK_STATE)) {
1874                        ret = _FAIL;
1875                        rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
1876                        goto exit;
1877                }
1878        }
1879
1880        /* check the frame crtl field and decache */
1881        ret = validate_recv_frame(padapter, rframe);
1882        if (ret != _SUCCESS) {
1883                rtw_free_recvframe(rframe, pfree_recv_queue);/* free this recv_frame */
1884                goto exit;
1885        }
1886
1887exit:
1888        return ret;
1889}
1890
1891static int recv_func_posthandle(struct adapter *padapter, struct recv_frame *prframe)
1892{
1893        int ret = _SUCCESS;
1894        struct recv_frame *orig_prframe = prframe;
1895        struct recv_priv *precvpriv = &padapter->recvpriv;
1896        struct __queue *pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1897
1898        /*  DATA FRAME */
1899        rtw_led_control(padapter, LED_CTL_RX);
1900
1901        prframe = decryptor(padapter, prframe);
1902        if (!prframe) {
1903                ret = _FAIL;
1904                goto _recv_data_drop;
1905        }
1906
1907        prframe = recvframe_chk_defrag(padapter, prframe);
1908        if (!prframe)
1909                goto _recv_data_drop;
1910
1911        prframe = portctrl(padapter, prframe);
1912        if (!prframe) {
1913                ret = _FAIL;
1914                goto _recv_data_drop;
1915        }
1916
1917        count_rx_stats(padapter, prframe, NULL);
1918
1919        ret = process_recv_indicatepkts(padapter, prframe);
1920        if (ret != _SUCCESS) {
1921                rtw_free_recvframe(orig_prframe, pfree_recv_queue);/* free this recv_frame */
1922                goto _recv_data_drop;
1923        }
1924        return ret;
1925
1926_recv_data_drop:
1927        precvpriv->rx_drop++;
1928        return ret;
1929}
1930
1931static int recv_func(struct adapter *padapter, struct recv_frame *rframe)
1932{
1933        int ret;
1934        struct rx_pkt_attrib *prxattrib = &rframe->attrib;
1935        struct security_priv *psecuritypriv = &padapter->securitypriv;
1936        struct mlme_priv *mlmepriv = &padapter->mlmepriv;
1937        struct recv_priv *recvpriv = &padapter->recvpriv;
1938
1939        /* check if need to handle uc_swdec_pending_queue*/
1940        if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
1941            psecuritypriv->busetkipkey) {
1942                struct recv_frame *pending_frame;
1943                int cnt = 0;
1944
1945                pending_frame = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
1946                while (pending_frame) {
1947                        cnt++;
1948                        recv_func_posthandle(padapter, pending_frame);
1949                }
1950        }
1951
1952        ret = recv_func_prehandle(padapter, rframe);
1953
1954        if (ret == _SUCCESS) {
1955                /* check if need to enqueue into uc_swdec_pending_queue*/
1956                if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
1957                    !is_multicast_ether_addr(prxattrib->ra) && prxattrib->encrypt > 0 &&
1958                    (prxattrib->bdecrypted == 0 || psecuritypriv->sw_decrypt) &&
1959                     psecuritypriv->ndisauthtype == Ndis802_11AuthModeWPAPSK &&
1960                     !psecuritypriv->busetkipkey) {
1961                        rtw_enqueue_recvframe(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
1962                        DBG_88E("%s: no key, enqueue uc_swdec_pending_queue\n", __func__);
1963                        if (recvpriv->free_recvframe_cnt < NR_RECVFRAME / 4) {
1964                                /* to prevent from recvframe starvation,
1965                                 * get recvframe from uc_swdec_pending_queue to
1966                                 * free_recvframe_cnt  */
1967                                rframe = rtw_alloc_recvframe(&padapter->recvpriv.uc_swdec_pending_queue);
1968                                if (rframe)
1969                                        goto do_posthandle;
1970                        }
1971                        goto exit;
1972                }
1973do_posthandle:
1974                ret = recv_func_posthandle(padapter, rframe);
1975        }
1976
1977exit:
1978        return ret;
1979}
1980
1981s32 rtw_recv_entry(struct recv_frame *precvframe)
1982{
1983        struct adapter *padapter;
1984        struct recv_priv *precvpriv;
1985        s32 ret = _SUCCESS;
1986
1987        padapter = precvframe->adapter;
1988
1989        precvpriv = &padapter->recvpriv;
1990
1991        ret = recv_func(padapter, precvframe);
1992        if (ret == _FAIL)
1993                goto _recv_entry_drop;
1994
1995        precvpriv->rx_pkts++;
1996
1997        return ret;
1998
1999_recv_entry_drop:
2000
2001        if (padapter->registrypriv.mp_mode == 1)
2002                padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
2003
2004        return ret;
2005}
2006
2007void rtw_signal_stat_timer_hdl(struct timer_list *t)
2008{
2009        struct adapter *adapter = from_timer(adapter, t, recvpriv.signal_stat_timer);
2010        struct recv_priv *recvpriv = &adapter->recvpriv;
2011
2012        u32 tmp_s, tmp_q;
2013        u8 avg_signal_strength = 0;
2014        u8 avg_signal_qual = 0;
2015        u8 _alpha = 3; /*  this value is based on converging_constant = 5000 and sampling_interval = 1000 */
2016
2017        if (adapter->recvpriv.is_signal_dbg) {
2018                /* update the user specific value, signal_strength_dbg, to signal_strength, rssi */
2019                adapter->recvpriv.signal_strength = adapter->recvpriv.signal_strength_dbg;
2020                adapter->recvpriv.rssi = (s8)translate_percentage_to_dbm((u8)adapter->recvpriv.signal_strength_dbg);
2021        } else {
2022                if (recvpriv->signal_strength_data.update_req == 0) {/*  update_req is clear, means we got rx */
2023                        avg_signal_strength = recvpriv->signal_strength_data.avg_val;
2024                        /*  after avg_vals are accquired, we can re-stat the signal values */
2025                        recvpriv->signal_strength_data.update_req = 1;
2026                }
2027
2028                if (recvpriv->signal_qual_data.update_req == 0) {/*  update_req is clear, means we got rx */
2029                        avg_signal_qual = recvpriv->signal_qual_data.avg_val;
2030                        /*  after avg_vals are accquired, we can re-stat the signal values */
2031                        recvpriv->signal_qual_data.update_req = 1;
2032                }
2033
2034                /* update value of signal_strength, rssi, signal_qual */
2035                if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
2036                        tmp_s = (avg_signal_strength + (_alpha - 1) * recvpriv->signal_strength);
2037                        if (tmp_s % _alpha)
2038                                tmp_s = tmp_s / _alpha + 1;
2039                        else
2040                                tmp_s = tmp_s / _alpha;
2041                        if (tmp_s > 100)
2042                                tmp_s = 100;
2043
2044                        tmp_q = (avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual);
2045                        if (tmp_q % _alpha)
2046                                tmp_q = tmp_q / _alpha + 1;
2047                        else
2048                                tmp_q = tmp_q / _alpha;
2049                        if (tmp_q > 100)
2050                                tmp_q = 100;
2051
2052                        recvpriv->signal_strength = tmp_s;
2053                        recvpriv->rssi = (s8)translate_percentage_to_dbm(tmp_s);
2054                        recvpriv->signal_qual = tmp_q;
2055                }
2056        }
2057        rtw_set_signal_stat_timer(recvpriv);
2058}
2059