linux/drivers/staging/rtl8723au/core/rtw_recv.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 *
  14 ******************************************************************************/
  15#define _RTW_RECV_C_
  16#include <osdep_service.h>
  17#include <drv_types.h>
  18#include <recv_osdep.h>
  19#include <mlme_osdep.h>
  20#include <linux/ip.h>
  21#include <linux/if_ether.h>
  22#include <usb_ops.h>
  23#include <linux/ieee80211.h>
  24#include <wifi.h>
  25#include <rtl8723a_recv.h>
  26#include <rtl8723a_xmit.h>
  27
  28void rtw_signal_stat_timer_hdl23a(unsigned long data);
  29
  30void _rtw_init_sta_recv_priv23a(struct sta_recv_priv *psta_recvpriv)
  31{
  32
  33
  34
  35        spin_lock_init(&psta_recvpriv->lock);
  36
  37        /* for (i = 0; i<MAX_RX_NUMBLKS; i++) */
  38        /*      _rtw_init_queue23a(&psta_recvpriv->blk_strms[i]); */
  39
  40        _rtw_init_queue23a(&psta_recvpriv->defrag_q);
  41
  42
  43}
  44
  45int _rtw_init_recv_priv23a(struct recv_priv *precvpriv,
  46                        struct rtw_adapter *padapter)
  47{
  48        struct recv_frame *precvframe;
  49        int i;
  50        int res = _SUCCESS;
  51
  52        spin_lock_init(&precvpriv->lock);
  53
  54        _rtw_init_queue23a(&precvpriv->free_recv_queue);
  55        _rtw_init_queue23a(&precvpriv->recv_pending_queue);
  56        _rtw_init_queue23a(&precvpriv->uc_swdec_pending_queue);
  57
  58        precvpriv->adapter = padapter;
  59
  60        for (i = 0; i < NR_RECVFRAME ; i++) {
  61                precvframe = kzalloc(sizeof(struct recv_frame), GFP_KERNEL);
  62                if (!precvframe)
  63                        break;
  64                INIT_LIST_HEAD(&precvframe->list);
  65
  66                list_add_tail(&precvframe->list,
  67                              &precvpriv->free_recv_queue.queue);
  68
  69                precvframe->adapter = padapter;
  70                precvframe++;
  71        }
  72
  73        precvpriv->free_recvframe_cnt = i;
  74        precvpriv->rx_pending_cnt = 1;
  75
  76        res = rtl8723au_init_recv_priv(padapter);
  77
  78        setup_timer(&precvpriv->signal_stat_timer, rtw_signal_stat_timer_hdl23a,
  79                    (unsigned long)padapter);
  80
  81        precvpriv->signal_stat_sampling_interval = 1000; /* ms */
  82
  83        rtw_set_signal_stat_timer(precvpriv);
  84
  85        return res;
  86}
  87
  88void _rtw_free_recv_priv23a (struct recv_priv *precvpriv)
  89{
  90        struct rtw_adapter *padapter = precvpriv->adapter;
  91        struct recv_frame *precvframe;
  92        struct list_head *plist, *ptmp;
  93
  94        rtw_free_uc_swdec_pending_queue23a(padapter);
  95
  96        list_for_each_safe(plist, ptmp, &precvpriv->free_recv_queue.queue) {
  97                precvframe = container_of(plist, struct recv_frame, list);
  98                list_del_init(&precvframe->list);
  99                kfree(precvframe);
 100        }
 101
 102        rtl8723au_free_recv_priv(padapter);
 103}
 104
 105struct recv_frame *rtw_alloc_recvframe23a(struct rtw_queue *pfree_recv_queue)
 106{
 107        struct recv_frame *pframe;
 108        struct list_head *plist, *phead;
 109        struct rtw_adapter *padapter;
 110        struct recv_priv *precvpriv;
 111
 112        spin_lock_bh(&pfree_recv_queue->lock);
 113
 114        if (list_empty(&pfree_recv_queue->queue))
 115                pframe = NULL;
 116        else {
 117                phead = get_list_head(pfree_recv_queue);
 118
 119                plist = phead->next;
 120
 121                pframe = container_of(plist, struct recv_frame, list);
 122
 123                list_del_init(&pframe->list);
 124                padapter = pframe->adapter;
 125                if (padapter) {
 126                        precvpriv = &padapter->recvpriv;
 127                        if (pfree_recv_queue == &precvpriv->free_recv_queue)
 128                                precvpriv->free_recvframe_cnt--;
 129                }
 130        }
 131
 132        spin_unlock_bh(&pfree_recv_queue->lock);
 133
 134        return pframe;
 135}
 136
 137int rtw_free_recvframe23a(struct recv_frame *precvframe)
 138{
 139        struct rtw_adapter *padapter = precvframe->adapter;
 140        struct recv_priv *precvpriv = &padapter->recvpriv;
 141        struct rtw_queue *pfree_recv_queue;
 142
 143        if (precvframe->pkt) {
 144                dev_kfree_skb_any(precvframe->pkt);/* free skb by driver */
 145                precvframe->pkt = NULL;
 146        }
 147
 148        pfree_recv_queue = &precvpriv->free_recv_queue;
 149        spin_lock_bh(&pfree_recv_queue->lock);
 150
 151        list_del_init(&precvframe->list);
 152
 153        list_add_tail(&precvframe->list, get_list_head(pfree_recv_queue));
 154
 155        if (padapter) {
 156                if (pfree_recv_queue == &precvpriv->free_recv_queue)
 157                        precvpriv->free_recvframe_cnt++;
 158        }
 159
 160        spin_unlock_bh(&pfree_recv_queue->lock);
 161
 162
 163
 164        return _SUCCESS;
 165}
 166
 167int rtw_enqueue_recvframe23a(struct recv_frame *precvframe, struct rtw_queue *queue)
 168{
 169        struct rtw_adapter *padapter = precvframe->adapter;
 170        struct recv_priv *precvpriv = &padapter->recvpriv;
 171
 172        spin_lock_bh(&queue->lock);
 173
 174        list_del_init(&precvframe->list);
 175
 176        list_add_tail(&precvframe->list, get_list_head(queue));
 177
 178        if (padapter) {
 179                if (queue == &precvpriv->free_recv_queue)
 180                        precvpriv->free_recvframe_cnt++;
 181        }
 182
 183        spin_unlock_bh(&queue->lock);
 184
 185        return _SUCCESS;
 186}
 187
 188/*
 189caller : defrag ; recvframe_chk_defrag23a in recv_thread  (passive)
 190pframequeue: defrag_queue : will be accessed in recv_thread  (passive)
 191
 192using spinlock to protect
 193
 194*/
 195
 196static void rtw_free_recvframe23a_queue(struct rtw_queue *pframequeue)
 197{
 198        struct recv_frame *hdr;
 199        struct list_head *plist, *phead, *ptmp;
 200
 201        spin_lock(&pframequeue->lock);
 202
 203        phead = get_list_head(pframequeue);
 204        plist = phead->next;
 205
 206        list_for_each_safe(plist, ptmp, phead) {
 207                hdr = container_of(plist, struct recv_frame, list);
 208                rtw_free_recvframe23a(hdr);
 209        }
 210
 211        spin_unlock(&pframequeue->lock);
 212}
 213
 214u32 rtw_free_uc_swdec_pending_queue23a(struct rtw_adapter *adapter)
 215{
 216        u32 cnt = 0;
 217        struct recv_frame *pending_frame;
 218
 219        while ((pending_frame = rtw_alloc_recvframe23a(&adapter->recvpriv.uc_swdec_pending_queue))) {
 220                rtw_free_recvframe23a(pending_frame);
 221                DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
 222                cnt++;
 223        }
 224
 225        return cnt;
 226}
 227
 228int rtw_enqueue_recvbuf23a_to_head(struct recv_buf *precvbuf, struct rtw_queue *queue)
 229{
 230        spin_lock_bh(&queue->lock);
 231
 232        list_del_init(&precvbuf->list);
 233        list_add(&precvbuf->list, get_list_head(queue));
 234
 235        spin_unlock_bh(&queue->lock);
 236
 237        return _SUCCESS;
 238}
 239
 240int rtw_enqueue_recvbuf23a(struct recv_buf *precvbuf, struct rtw_queue *queue)
 241{
 242        unsigned long irqL;
 243
 244        spin_lock_irqsave(&queue->lock, irqL);
 245
 246        list_del_init(&precvbuf->list);
 247
 248        list_add_tail(&precvbuf->list, get_list_head(queue));
 249        spin_unlock_irqrestore(&queue->lock, irqL);
 250        return _SUCCESS;
 251}
 252
 253struct recv_buf *rtw_dequeue_recvbuf23a (struct rtw_queue *queue)
 254{
 255        unsigned long irqL;
 256        struct recv_buf *precvbuf;
 257        struct list_head *plist, *phead;
 258
 259        spin_lock_irqsave(&queue->lock, irqL);
 260
 261        if (list_empty(&queue->queue)) {
 262                precvbuf = NULL;
 263        } else {
 264                phead = get_list_head(queue);
 265
 266                plist = phead->next;
 267
 268                precvbuf = container_of(plist, struct recv_buf, list);
 269
 270                list_del_init(&precvbuf->list);
 271        }
 272
 273        spin_unlock_irqrestore(&queue->lock, irqL);
 274
 275        return precvbuf;
 276}
 277
 278int recvframe_chkmic(struct rtw_adapter *adapter,
 279                     struct recv_frame *precvframe);
 280int recvframe_chkmic(struct rtw_adapter *adapter,
 281                     struct recv_frame *precvframe) {
 282
 283        int     i, res = _SUCCESS;
 284        u32     datalen;
 285        u8      miccode[8];
 286        u8      bmic_err = false, brpt_micerror = true;
 287        u8      *pframe, *payload, *pframemic;
 288        u8      *mickey;
 289        /* u8   *iv, rxdata_key_idx = 0; */
 290        struct  sta_info *stainfo;
 291        struct  rx_pkt_attrib *prxattrib = &precvframe->attrib;
 292        struct  security_priv *psecuritypriv = &adapter->securitypriv;
 293
 294        struct mlme_ext_priv *pmlmeext = &adapter->mlmeextpriv;
 295        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 296
 297
 298        stainfo = rtw_get_stainfo23a(&adapter->stapriv, &prxattrib->ta[0]);
 299
 300        if (prxattrib->encrypt == WLAN_CIPHER_SUITE_TKIP) {
 301                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 302                         "recvframe_chkmic:prxattrib->encrypt == WLAN_CIPHER_SUITE_TKIP\n");
 303                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 304                         "recvframe_chkmic:da = %pM\n", prxattrib->ra);
 305
 306                /* calculate mic code */
 307                if (stainfo != NULL) {
 308                        if (is_multicast_ether_addr(prxattrib->ra)) {
 309                                mickey = &psecuritypriv->dot118021XGrprxmickey[prxattrib->key_index].skey[0];
 310
 311                                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 312                                         "recvframe_chkmic: bcmc key\n");
 313
 314                                if (!psecuritypriv->binstallGrpkey) {
 315                                        res = _FAIL;
 316                                        RT_TRACE(_module_rtl871x_recv_c_,
 317                                                 _drv_err_,
 318                                                 "recvframe_chkmic:didn't install group key!\n");
 319                                        DBG_8723A("\n recvframe_chkmic:didn't "
 320                                                  "install group key!!!!!!\n");
 321                                        goto exit;
 322                                }
 323                        } else {
 324                                mickey = &stainfo->dot11tkiprxmickey.skey[0];
 325                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 326                                         "recvframe_chkmic: unicast key\n");
 327                        }
 328
 329                        /* icv_len included the mic code */
 330                        datalen = precvframe->pkt->len-prxattrib->
 331                                hdrlen-prxattrib->iv_len-prxattrib->icv_len - 8;
 332                        pframe = precvframe->pkt->data;
 333                        payload = pframe + prxattrib->hdrlen +
 334                                prxattrib->iv_len;
 335
 336                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 337                                 "prxattrib->iv_len =%d prxattrib->icv_len =%d\n",
 338                                 prxattrib->iv_len, prxattrib->icv_len);
 339
 340                        /* care the length of the data */
 341                        rtw_seccalctkipmic23a(mickey, pframe, payload,
 342                                           datalen, &miccode[0],
 343                                           (unsigned char)prxattrib->priority);
 344
 345                        pframemic = payload + datalen;
 346
 347                        bmic_err = false;
 348
 349                        for (i = 0; i < 8; i++) {
 350                                if (miccode[i] != *(pframemic + i)) {
 351                                        RT_TRACE(_module_rtl871x_recv_c_,
 352                                                 _drv_err_,
 353                                                 "recvframe_chkmic:miccode[%d](%02x) != *(pframemic+%d)(%02x)\n",
 354                                                 i, miccode[i],
 355                                                 i, *(pframemic + i));
 356                                        bmic_err = true;
 357                                }
 358                        }
 359
 360                        if (bmic_err == true) {
 361                                int i;
 362
 363                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 364                                         "*(pframemic-8)-*(pframemic-1) =0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
 365                                         *(pframemic - 8), *(pframemic - 7),
 366                                         *(pframemic - 6), *(pframemic - 5),
 367                                         *(pframemic - 4), *(pframemic - 3),
 368                                         *(pframemic - 2), *(pframemic - 1));
 369                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 370                                         "*(pframemic-16)-*(pframemic-9) =0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
 371                                         *(pframemic - 16), *(pframemic - 15),
 372                                         *(pframemic - 14), *(pframemic - 13),
 373                                         *(pframemic - 12), *(pframemic - 11),
 374                                         *(pframemic - 10), *(pframemic - 9));
 375
 376                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 377                                         "====== demp packet (len =%d) ======\n",
 378                                         precvframe->pkt->len);
 379                                for (i = 0; i < precvframe->pkt->len; i = i + 8) {
 380                                        RT_TRACE(_module_rtl871x_recv_c_,
 381                                                 _drv_err_,
 382                                                 "0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x\n",
 383                                                 *(precvframe->pkt->data+i),
 384                                                 *(precvframe->pkt->data+i+1),
 385                                                 *(precvframe->pkt->data+i+2),
 386                                                 *(precvframe->pkt->data+i+3),
 387                                                 *(precvframe->pkt->data+i+4),
 388                                                 *(precvframe->pkt->data+i+5),
 389                                                 *(precvframe->pkt->data+i+6),
 390                                                 *(precvframe->pkt->data+i+7));
 391                                }
 392                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 393                                         "====== demp packet end [len =%d]======\n",
 394                                         precvframe->pkt->len);
 395                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 396                                         "hrdlen =%d\n", prxattrib->hdrlen);
 397
 398                                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 399                                         "ra = %pM psecuritypriv->binstallGrpkey =%d\n",
 400                                         prxattrib->ra,
 401                                         psecuritypriv->binstallGrpkey);
 402
 403                                /*  double check key_index for some timing
 404                                    issue, cannot compare with
 405                                    psecuritypriv->dot118021XGrpKeyid also
 406                                    cause timing issue */
 407                                if ((is_multicast_ether_addr(prxattrib->ra)) &&
 408                                    (prxattrib->key_index !=
 409                                     pmlmeinfo->key_index))
 410                                        brpt_micerror = false;
 411
 412                                if ((prxattrib->bdecrypted == true) &&
 413                                    (brpt_micerror == true)) {
 414                                        rtw_handle_tkip_mic_err23a(adapter, (u8)is_multicast_ether_addr(prxattrib->ra));
 415                                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 416                                                 "mic error :prxattrib->bdecrypted =%d\n",
 417                                                 prxattrib->bdecrypted);
 418                                        DBG_8723A(" mic error :prxattrib->"
 419                                                  "bdecrypted =%d\n",
 420                                                  prxattrib->bdecrypted);
 421                                } else {
 422                                        RT_TRACE(_module_rtl871x_recv_c_,
 423                                                 _drv_err_,
 424                                                 "mic error :prxattrib->bdecrypted =%d\n",
 425                                                 prxattrib->bdecrypted);
 426                                        DBG_8723A(" mic error :prxattrib->"
 427                                                  "bdecrypted =%d\n",
 428                                                  prxattrib->bdecrypted);
 429                                }
 430
 431                                res = _FAIL;
 432                        } else {
 433                                /* mic checked ok */
 434                                if (!psecuritypriv->bcheck_grpkey &&
 435                                    is_multicast_ether_addr(prxattrib->ra)) {
 436                                        psecuritypriv->bcheck_grpkey = 1;
 437                                        RT_TRACE(_module_rtl871x_recv_c_,
 438                                                 _drv_err_,
 439                                                 "psecuritypriv->bcheck_grpkey = true\n");
 440                                }
 441                        }
 442                } else {
 443                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 444                                 "recvframe_chkmic: rtw_get_stainfo23a ==NULL!!!\n");
 445                }
 446
 447                skb_trim(precvframe->pkt, precvframe->pkt->len - 8);
 448        }
 449
 450exit:
 451
 452
 453
 454        return res;
 455}
 456
 457/* decrypt and set the ivlen, icvlen of the recv_frame */
 458struct recv_frame *decryptor(struct rtw_adapter *padapter,
 459                             struct recv_frame *precv_frame);
 460struct recv_frame *decryptor(struct rtw_adapter *padapter,
 461                             struct recv_frame *precv_frame)
 462{
 463        struct rx_pkt_attrib *prxattrib = &precv_frame->attrib;
 464        struct security_priv *psecuritypriv = &padapter->securitypriv;
 465        struct recv_frame *return_packet = precv_frame;
 466        int res = _SUCCESS;
 467
 468        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 469                 "prxstat->decrypted =%x prxattrib->encrypt = 0x%03x\n",
 470                 prxattrib->bdecrypted, prxattrib->encrypt);
 471
 472        if (prxattrib->encrypt > 0) {
 473                u8 *iv = precv_frame->pkt->data + prxattrib->hdrlen;
 474
 475                prxattrib->key_index = (((iv[3]) >> 6) & 0x3);
 476
 477                if (prxattrib->key_index > WEP_KEYS) {
 478                        DBG_8723A("prxattrib->key_index(%d) > WEP_KEYS\n",
 479                                  prxattrib->key_index);
 480
 481                        switch (prxattrib->encrypt) {
 482                        case WLAN_CIPHER_SUITE_WEP40:
 483                        case WLAN_CIPHER_SUITE_WEP104:
 484                                prxattrib->key_index =
 485                                        psecuritypriv->dot11PrivacyKeyIndex;
 486                                break;
 487                        case WLAN_CIPHER_SUITE_TKIP:
 488                        case WLAN_CIPHER_SUITE_CCMP:
 489                        default:
 490                                prxattrib->key_index =
 491                                        psecuritypriv->dot118021XGrpKeyid;
 492                                break;
 493                        }
 494                }
 495        }
 496
 497        if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0))) {
 498                psecuritypriv->hw_decrypted = 0;
 499                switch (prxattrib->encrypt) {
 500                case WLAN_CIPHER_SUITE_WEP40:
 501                case WLAN_CIPHER_SUITE_WEP104:
 502                        rtw_wep_decrypt23a(padapter, precv_frame);
 503                        break;
 504                case WLAN_CIPHER_SUITE_TKIP:
 505                        res = rtw_tkip_decrypt23a(padapter, precv_frame);
 506                        break;
 507                case WLAN_CIPHER_SUITE_CCMP:
 508                        res = rtw_aes_decrypt23a(padapter, precv_frame);
 509                        break;
 510                default:
 511                        break;
 512                }
 513        } else if (prxattrib->bdecrypted == 1 && prxattrib->encrypt > 0 &&
 514                   (psecuritypriv->busetkipkey == 1 ||
 515                    prxattrib->encrypt != WLAN_CIPHER_SUITE_TKIP)) {
 516                        psecuritypriv->hw_decrypted = 1;
 517        }
 518
 519        if (res == _FAIL) {
 520                rtw_free_recvframe23a(return_packet);
 521                return_packet = NULL;
 522        }
 523
 524
 525
 526        return return_packet;
 527}
 528
 529/* set the security information in the recv_frame */
 530static struct recv_frame *portctrl(struct rtw_adapter *adapter,
 531                                   struct recv_frame *precv_frame)
 532{
 533        u8 *psta_addr, *ptr;
 534        uint auth_alg;
 535        struct recv_frame *pfhdr;
 536        struct sta_info *psta;
 537        struct sta_priv *pstapriv ;
 538        struct recv_frame *prtnframe;
 539        u16 ether_type;
 540        u16 eapol_type = ETH_P_PAE;/* for Funia BD's WPA issue */
 541        struct rx_pkt_attrib *pattrib;
 542
 543        pstapriv = &adapter->stapriv;
 544
 545        auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
 546
 547        pfhdr = precv_frame;
 548        pattrib = &pfhdr->attrib;
 549        psta_addr = pattrib->ta;
 550        psta = rtw_get_stainfo23a(pstapriv, psta_addr);
 551
 552        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 553                 "########portctrl:adapter->securitypriv.dot11AuthAlgrthm =%d\n",
 554                 adapter->securitypriv.dot11AuthAlgrthm);
 555
 556        prtnframe = precv_frame;
 557
 558        if (auth_alg == dot11AuthAlgrthm_8021X) {
 559                /* get ether_type */
 560                ptr = pfhdr->pkt->data + pfhdr->attrib.hdrlen;
 561
 562                ether_type = (ptr[6] << 8) | ptr[7];
 563
 564                if (psta && psta->ieee8021x_blocked) {
 565                        /* blocked */
 566                        /* only accept EAPOL frame */
 567                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 568                                 "########portctrl:psta->ieee8021x_blocked ==1\n");
 569
 570                        if (ether_type != eapol_type) {
 571                                /* free this frame */
 572                                rtw_free_recvframe23a(precv_frame);
 573                                prtnframe = NULL;
 574                        }
 575                }
 576        }
 577
 578        return prtnframe;
 579}
 580
 581int recv_decache(struct recv_frame *precv_frame, u8 bretry,
 582                 struct stainfo_rxcache *prxcache);
 583int recv_decache(struct recv_frame *precv_frame, u8 bretry,
 584                 struct stainfo_rxcache *prxcache)
 585{
 586        int tid = precv_frame->attrib.priority;
 587
 588        u16 seq_ctrl = ((precv_frame->attrib.seq_num & 0xffff) << 4) |
 589                (precv_frame->attrib.frag_num & 0xf);
 590
 591
 592
 593        if (tid > 15) {
 594                RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
 595                         "recv_decache, (tid>15)! seq_ctrl = 0x%x, tid = 0x%x\n",
 596                         seq_ctrl, tid);
 597
 598                return _FAIL;
 599        }
 600
 601        if (1) { /* if (bretry) */
 602                if (seq_ctrl == prxcache->tid_rxseq[tid]) {
 603                        RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
 604                                 "recv_decache, seq_ctrl = 0x%x, tid = 0x%x, tid_rxseq = 0x%x\n",
 605                                 seq_ctrl, tid, prxcache->tid_rxseq[tid]);
 606
 607                        return _FAIL;
 608                }
 609        }
 610
 611        prxcache->tid_rxseq[tid] = seq_ctrl;
 612
 613
 614
 615        return _SUCCESS;
 616}
 617
 618void process23a_pwrbit_data(struct rtw_adapter *padapter,
 619                         struct recv_frame *precv_frame);
 620void process23a_pwrbit_data(struct rtw_adapter *padapter,
 621                         struct recv_frame *precv_frame)
 622{
 623#ifdef CONFIG_8723AU_AP_MODE
 624        unsigned char pwrbit;
 625        struct sk_buff *skb = precv_frame->pkt;
 626        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 627        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 628        struct sta_priv *pstapriv = &padapter->stapriv;
 629        struct sta_info *psta = NULL;
 630
 631        psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
 632
 633        if (psta) {
 634                pwrbit = ieee80211_has_pm(hdr->frame_control);
 635
 636                if (pwrbit) {
 637                        if (!(psta->state & WIFI_SLEEP_STATE))
 638                                stop_sta_xmit23a(padapter, psta);
 639                } else {
 640                        if (psta->state & WIFI_SLEEP_STATE)
 641                                wakeup_sta_to_xmit23a(padapter, psta);
 642                }
 643        }
 644
 645#endif
 646}
 647
 648void process_wmmps_data(struct rtw_adapter *padapter,
 649                        struct recv_frame *precv_frame);
 650void process_wmmps_data(struct rtw_adapter *padapter,
 651                        struct recv_frame *precv_frame)
 652{
 653#ifdef CONFIG_8723AU_AP_MODE
 654        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
 655        struct sta_priv *pstapriv = &padapter->stapriv;
 656        struct sta_info *psta = NULL;
 657
 658        psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
 659
 660        if (!psta)
 661                return;
 662
 663
 664        if (!psta->qos_option)
 665                return;
 666
 667        if (!(psta->qos_info & 0xf))
 668                return;
 669
 670        if (psta->state & WIFI_SLEEP_STATE) {
 671                u8 wmmps_ac = 0;
 672
 673                switch (pattrib->priority) {
 674                case 1:
 675                case 2:
 676                        wmmps_ac = psta->uapsd_bk & BIT(1);
 677                        break;
 678                case 4:
 679                case 5:
 680                        wmmps_ac = psta->uapsd_vi & BIT(1);
 681                        break;
 682                case 6:
 683                case 7:
 684                        wmmps_ac = psta->uapsd_vo & BIT(1);
 685                        break;
 686                case 0:
 687                case 3:
 688                default:
 689                        wmmps_ac = psta->uapsd_be & BIT(1);
 690                        break;
 691                }
 692
 693                if (wmmps_ac) {
 694                        if (psta->sleepq_ac_len > 0) {
 695                                /* process received triggered frame */
 696                                xmit_delivery_enabled_frames23a(padapter, psta);
 697                        } else {
 698                                /* issue one qos null frame with More data bit = 0 and the EOSP bit set (= 1) */
 699                                issue_qos_nulldata23a(padapter, psta->hwaddr,
 700                                                   (u16)pattrib->priority,
 701                                                   0, 0);
 702                        }
 703                }
 704        }
 705
 706#endif
 707}
 708
 709static void count_rx_stats(struct rtw_adapter *padapter,
 710                           struct recv_frame *prframe, struct sta_info *sta)
 711{
 712        int sz;
 713        struct sta_info *psta = NULL;
 714        struct stainfo_stats *pstats = NULL;
 715        struct rx_pkt_attrib *pattrib = & prframe->attrib;
 716        struct recv_priv *precvpriv = &padapter->recvpriv;
 717
 718        sz = prframe->pkt->len;
 719        precvpriv->rx_bytes += sz;
 720
 721        padapter->mlmepriv.LinkDetectInfo.NumRxOkInPeriod++;
 722
 723        if ((!is_broadcast_ether_addr(pattrib->dst)) &&
 724            (!is_multicast_ether_addr(pattrib->dst)))
 725                padapter->mlmepriv.LinkDetectInfo.NumRxUnicastOkInPeriod++;
 726
 727        if (sta)
 728                psta = sta;
 729        else
 730                psta = prframe->psta;
 731
 732        if (psta) {
 733                pstats = &psta->sta_stats;
 734
 735                pstats->rx_data_pkts++;
 736                pstats->rx_bytes += sz;
 737        }
 738}
 739
 740static int sta2sta_data_frame(struct rtw_adapter *adapter,
 741                              struct recv_frame *precv_frame,
 742                              struct sta_info**psta)
 743{
 744        struct sk_buff *skb = precv_frame->pkt;
 745        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 746        int ret = _SUCCESS;
 747        struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
 748        struct sta_priv *pstapriv = &adapter->stapriv;
 749        struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
 750        u8 *mybssid  = get_bssid(pmlmepriv);
 751        u8 *myhwaddr = myid(&adapter->eeprompriv);
 752        u8 *sta_addr = NULL;
 753        int bmcast = is_multicast_ether_addr(pattrib->dst);
 754
 755
 756
 757        if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 758            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 759
 760                /*  filter packets that SA is myself or multicast or broadcast */
 761                if (ether_addr_equal(myhwaddr, pattrib->src)) {
 762                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 763                                 "SA == myself\n");
 764                        ret = _FAIL;
 765                        goto exit;
 766                }
 767
 768                if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
 769                        ret = _FAIL;
 770                        goto exit;
 771                }
 772
 773                if (ether_addr_equal(pattrib->bssid, "\x0\x0\x0\x0\x0\x0") ||
 774                    ether_addr_equal(mybssid, "\x0\x0\x0\x0\x0\x0") ||
 775                    !ether_addr_equal(pattrib->bssid, mybssid)) {
 776                        ret = _FAIL;
 777                        goto exit;
 778                }
 779
 780                sta_addr = pattrib->src;
 781        } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 782                /*  For Station mode, sa and bssid should always be BSSID,
 783                    and DA is my mac-address */
 784                if (!ether_addr_equal(pattrib->bssid, pattrib->src)) {
 785                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 786                                 "bssid != TA under STATION_MODE; drop pkt\n");
 787                        ret = _FAIL;
 788                        goto exit;
 789                }
 790
 791                sta_addr = pattrib->bssid;
 792
 793        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 794                if (bmcast) {
 795                        /*  For AP mode, if DA == MCAST, then BSSID should be also MCAST */
 796                        if (!is_multicast_ether_addr(pattrib->bssid)) {
 797                                ret = _FAIL;
 798                                goto exit;
 799                        }
 800                } else { /*  not mc-frame */
 801                        /*  For AP mode, if DA is non-MCAST, then it must
 802                            be BSSID, and bssid == BSSID */
 803                        if (!ether_addr_equal(pattrib->bssid, pattrib->dst)) {
 804                                ret = _FAIL;
 805                                goto exit;
 806                        }
 807
 808                        sta_addr = pattrib->src;
 809                }
 810        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 811                ether_addr_copy(pattrib->dst, hdr->addr1);
 812                ether_addr_copy(pattrib->src, hdr->addr2);
 813                ether_addr_copy(pattrib->bssid, hdr->addr3);
 814                ether_addr_copy(pattrib->ra, pattrib->dst);
 815                ether_addr_copy(pattrib->ta, pattrib->src);
 816
 817                sta_addr = mybssid;
 818        } else {
 819                ret  = _FAIL;
 820        }
 821
 822        if (bmcast)
 823                *psta = rtw_get_bcmc_stainfo23a(adapter);
 824        else
 825                *psta = rtw_get_stainfo23a(pstapriv, sta_addr); /*  get ap_info */
 826
 827        if (*psta == NULL) {
 828                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 829                         "can't get psta under sta2sta_data_frame ; drop pkt\n");
 830                ret = _FAIL;
 831                goto exit;
 832        }
 833
 834exit:
 835
 836        return ret;
 837}
 838
 839int ap2sta_data_frame(struct rtw_adapter *adapter,
 840                      struct recv_frame *precv_frame,
 841                      struct sta_info **psta);
 842int ap2sta_data_frame(struct rtw_adapter *adapter,
 843                      struct recv_frame *precv_frame,
 844                      struct sta_info **psta)
 845{
 846        struct sk_buff *skb = precv_frame->pkt;
 847        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 848        struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
 849        int ret = _SUCCESS;
 850        struct sta_priv *pstapriv = &adapter->stapriv;
 851        struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
 852        u8 *mybssid  = get_bssid(pmlmepriv);
 853        u8 *myhwaddr = myid(&adapter->eeprompriv);
 854        int bmcast = is_multicast_ether_addr(pattrib->dst);
 855
 856
 857
 858        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
 859            (check_fwstate(pmlmepriv, _FW_LINKED) ||
 860             check_fwstate(pmlmepriv, _FW_UNDER_LINKING))) {
 861
 862                /* filter packets that SA is myself or multicast or broadcast */
 863                if (ether_addr_equal(myhwaddr, pattrib->src)) {
 864                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 865                                 "SA == myself\n");
 866                        ret = _FAIL;
 867                        goto exit;
 868                }
 869
 870                /*  da should be for me */
 871                if (!ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
 872                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 873                                 "ap2sta_data_frame:  compare DA failed; DA=%pM\n",
 874                                 pattrib->dst);
 875                        ret = _FAIL;
 876                        goto exit;
 877                }
 878
 879                /*  check BSSID */
 880                if (ether_addr_equal(pattrib->bssid, "\x0\x0\x0\x0\x0\x0") ||
 881                    ether_addr_equal(mybssid, "\x0\x0\x0\x0\x0\x0") ||
 882                    !ether_addr_equal(pattrib->bssid, mybssid)) {
 883                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 884                                 "ap2sta_data_frame:  compare BSSID failed; BSSID=%pM\n",
 885                                 pattrib->bssid);
 886                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
 887                                 "mybssid=%pM\n", mybssid);
 888
 889                        if (!bmcast) {
 890                                DBG_8723A("issue_deauth23a to the nonassociated ap=%pM for the reason(7)\n",
 891                                          pattrib->bssid);
 892                                issue_deauth23a(adapter, pattrib->bssid,
 893                                             WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 894                        }
 895
 896                        ret = _FAIL;
 897                        goto exit;
 898                }
 899
 900                if (bmcast)
 901                        *psta = rtw_get_bcmc_stainfo23a(adapter);
 902                else
 903                        /*  get ap_info */
 904                        *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
 905
 906                if (*psta == NULL) {
 907                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 908                                 "ap2sta: can't get psta under STATION_MODE; drop pkt\n");
 909                        ret = _FAIL;
 910                        goto exit;
 911                }
 912
 913                if (ieee80211_is_nullfunc(hdr->frame_control)) {
 914                        /* No data, will not indicate to upper layer,
 915                           temporily count it here */
 916                        count_rx_stats(adapter, precv_frame, *psta);
 917                        ret = RTW_RX_HANDLED;
 918                        goto exit;
 919                }
 920
 921        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
 922                   check_fwstate(pmlmepriv, _FW_LINKED)) {
 923                ether_addr_copy(pattrib->dst, hdr->addr1);
 924                ether_addr_copy(pattrib->src, hdr->addr2);
 925                ether_addr_copy(pattrib->bssid, hdr->addr3);
 926                ether_addr_copy(pattrib->ra, pattrib->dst);
 927                ether_addr_copy(pattrib->ta, pattrib->src);
 928
 929                /*  */
 930                ether_addr_copy(pattrib->bssid,  mybssid);
 931
 932                /*  get sta_info */
 933                *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
 934                if (*psta == NULL) {
 935                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 936                                 "can't get psta under MP_MODE ; drop pkt\n");
 937                        ret = _FAIL;
 938                        goto exit;
 939                }
 940        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 941                /* Special case */
 942                ret = RTW_RX_HANDLED;
 943                goto exit;
 944        } else {
 945                if (ether_addr_equal(myhwaddr, pattrib->dst) && !bmcast) {
 946                        *psta = rtw_get_stainfo23a(pstapriv, pattrib->bssid);
 947                        if (*psta == NULL) {
 948                                DBG_8723A("issue_deauth23a to the ap=%pM for the reason(7)\n",
 949                                          pattrib->bssid);
 950
 951                                issue_deauth23a(adapter, pattrib->bssid,
 952                                             WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 953                        }
 954                }
 955
 956                ret = _FAIL;
 957        }
 958
 959exit:
 960
 961
 962
 963        return ret;
 964}
 965
 966int sta2ap_data_frame(struct rtw_adapter *adapter,
 967                      struct recv_frame *precv_frame,
 968                      struct sta_info **psta);
 969int sta2ap_data_frame(struct rtw_adapter *adapter,
 970                      struct recv_frame *precv_frame,
 971                      struct sta_info **psta)
 972{
 973        struct sk_buff *skb = precv_frame->pkt;
 974        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 975        struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
 976        struct sta_priv *pstapriv = &adapter->stapriv;
 977        struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
 978        unsigned char *mybssid = get_bssid(pmlmepriv);
 979        int ret = _SUCCESS;
 980
 981
 982
 983        if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 984                /* For AP mode, RA = BSSID, TX = STA(SRC_ADDR), A3 = DST_ADDR */
 985                if (!ether_addr_equal(pattrib->bssid, mybssid)) {
 986                        ret = _FAIL;
 987                        goto exit;
 988                }
 989
 990                *psta = rtw_get_stainfo23a(pstapriv, pattrib->src);
 991                if (*psta == NULL) {
 992                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
 993                                 "can't get psta under AP_MODE; drop pkt\n");
 994                        DBG_8723A("issue_deauth23a to sta=%pM for the reason(7)\n",
 995                                  pattrib->src);
 996
 997                        issue_deauth23a(adapter, pattrib->src,
 998                                     WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
 999
1000                        ret = RTW_RX_HANDLED;
1001                        goto exit;
1002                }
1003
1004                process23a_pwrbit_data(adapter, precv_frame);
1005
1006                /* We only get here if it's a data frame, so no need to
1007                 * confirm data frame type first */
1008                if (ieee80211_is_data_qos(hdr->frame_control))
1009                        process_wmmps_data(adapter, precv_frame);
1010
1011                if (ieee80211_is_nullfunc(hdr->frame_control)) {
1012                        /* No data, will not indicate to upper layer,
1013                           temporily count it here */
1014                        count_rx_stats(adapter, precv_frame, *psta);
1015                        ret = RTW_RX_HANDLED;
1016                        goto exit;
1017                }
1018        } else {
1019                u8 *myhwaddr = myid(&adapter->eeprompriv);
1020
1021                if (!ether_addr_equal(pattrib->ra, myhwaddr)) {
1022                        ret = RTW_RX_HANDLED;
1023                        goto exit;
1024                }
1025                DBG_8723A("issue_deauth23a to sta=%pM for the reason(7)\n",
1026                          pattrib->src);
1027                issue_deauth23a(adapter, pattrib->src,
1028                             WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA);
1029                ret = RTW_RX_HANDLED;
1030                goto exit;
1031        }
1032
1033exit:
1034
1035
1036
1037        return ret;
1038}
1039
1040static int validate_recv_ctrl_frame(struct rtw_adapter *padapter,
1041                                    struct recv_frame *precv_frame)
1042{
1043#ifdef CONFIG_8723AU_AP_MODE
1044        struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
1045        struct sta_priv *pstapriv = &padapter->stapriv;
1046        struct sk_buff *skb = precv_frame->pkt;
1047        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1048
1049        if (!ieee80211_is_ctl(hdr->frame_control))
1050                return _FAIL;
1051
1052        /* receive the frames that ra(a1) is my address */
1053        if (!ether_addr_equal(hdr->addr1, myid(&padapter->eeprompriv)))
1054                return _FAIL;
1055
1056        /* only handle ps-poll */
1057        if (ieee80211_is_pspoll(hdr->frame_control)) {
1058                struct ieee80211_pspoll *psp = (struct ieee80211_pspoll *)hdr;
1059                u16 aid;
1060                u8 wmmps_ac = 0;
1061                struct sta_info *psta = NULL;
1062
1063                aid = le16_to_cpu(psp->aid) & 0x3fff;
1064                psta = rtw_get_stainfo23a(pstapriv, hdr->addr2);
1065
1066                if (!psta || psta->aid != aid)
1067                        return _FAIL;
1068
1069                /* for rx pkt statistics */
1070                psta->sta_stats.rx_ctrl_pkts++;
1071
1072                switch (pattrib->priority) {
1073                case 1:
1074                case 2:
1075                        wmmps_ac = psta->uapsd_bk & BIT(0);
1076                        break;
1077                case 4:
1078                case 5:
1079                        wmmps_ac = psta->uapsd_vi & BIT(0);
1080                        break;
1081                case 6:
1082                case 7:
1083                        wmmps_ac = psta->uapsd_vo & BIT(0);
1084                        break;
1085                case 0:
1086                case 3:
1087                default:
1088                        wmmps_ac = psta->uapsd_be & BIT(0);
1089                        break;
1090                }
1091
1092                if (wmmps_ac)
1093                        return _FAIL;
1094
1095                if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
1096                        DBG_8723A("%s alive check-rx ps-poll\n", __func__);
1097                        psta->expire_to = pstapriv->expire_to;
1098                        psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
1099                }
1100
1101                if ((psta->state & WIFI_SLEEP_STATE) &&
1102                    (pstapriv->sta_dz_bitmap & CHKBIT(psta->aid))) {
1103                        struct list_head *xmitframe_plist, *xmitframe_phead;
1104                        struct xmit_frame *pxmitframe;
1105                        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1106
1107                        spin_lock_bh(&pxmitpriv->lock);
1108
1109                        xmitframe_phead = get_list_head(&psta->sleep_q);
1110                        xmitframe_plist = xmitframe_phead->next;
1111
1112                        if (!list_empty(xmitframe_phead)) {
1113                                pxmitframe = container_of(xmitframe_plist,
1114                                                          struct xmit_frame,
1115                                                          list);
1116
1117                                xmitframe_plist = xmitframe_plist->next;
1118
1119                                list_del_init(&pxmitframe->list);
1120
1121                                psta->sleepq_len--;
1122
1123                                if (psta->sleepq_len>0)
1124                                        pxmitframe->attrib.mdata = 1;
1125                                else
1126                                        pxmitframe->attrib.mdata = 0;
1127
1128                                pxmitframe->attrib.triggered = 1;
1129
1130                                /* DBG_8723A("handling ps-poll, q_len =%d, tim =%x\n", psta->sleepq_len, pstapriv->tim_bitmap); */
1131
1132                                rtl8723au_hal_xmitframe_enqueue(padapter,
1133                                                                pxmitframe);
1134
1135                                if (psta->sleepq_len == 0) {
1136                                        pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
1137
1138                                        /* DBG_8723A("after handling ps-poll, tim =%x\n", pstapriv->tim_bitmap); */
1139
1140                                        /* update BCN for TIM IE */
1141                                        /* update_BCNTIM(padapter); */
1142                                        update_beacon23a(padapter, WLAN_EID_TIM,
1143                                                         NULL, false);
1144                                }
1145
1146                                /* spin_unlock_bh(&psta->sleep_q.lock); */
1147                                spin_unlock_bh(&pxmitpriv->lock);
1148
1149                        } else {
1150                                /* spin_unlock_bh(&psta->sleep_q.lock); */
1151                                spin_unlock_bh(&pxmitpriv->lock);
1152
1153                                /* DBG_8723A("no buffered packets to xmit\n"); */
1154                                if (pstapriv->tim_bitmap & CHKBIT(psta->aid)) {
1155                                        if (psta->sleepq_len == 0) {
1156                                                DBG_8723A("no buffered packets "
1157                                                          "to xmit\n");
1158
1159                                                /* issue nulldata with More data bit = 0 to indicate we have no buffered packets */
1160                                                issue_nulldata23a(padapter,
1161                                                               psta->hwaddr,
1162                                                               0, 0, 0);
1163                                        } else {
1164                                                DBG_8723A("error!psta->sleepq"
1165                                                          "_len =%d\n",
1166                                                          psta->sleepq_len);
1167                                                psta->sleepq_len = 0;
1168                                        }
1169
1170                                        pstapriv->tim_bitmap &= ~CHKBIT(psta->aid);
1171
1172                                        /* update BCN for TIM IE */
1173                                        /* update_BCNTIM(padapter); */
1174                                        update_beacon23a(padapter, WLAN_EID_TIM,
1175                                                         NULL, false);
1176                                }
1177                        }
1178                }
1179        }
1180
1181#endif
1182        return _FAIL;
1183}
1184
1185struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1186                                        struct recv_frame *precv_frame);
1187static int validate_recv_mgnt_frame(struct rtw_adapter *padapter,
1188                                    struct recv_frame *precv_frame)
1189{
1190        struct sta_info *psta;
1191        struct sk_buff *skb;
1192        struct ieee80211_hdr *hdr;
1193        /* struct mlme_priv *pmlmepriv = &adapter->mlmepriv; */
1194
1195        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1196                 "+validate_recv_mgnt_frame\n");
1197
1198        precv_frame = recvframe_chk_defrag23a(padapter, precv_frame);
1199        if (precv_frame == NULL) {
1200                RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1201                         "%s: fragment packet\n", __func__);
1202                return _SUCCESS;
1203        }
1204
1205        skb = precv_frame->pkt;
1206        hdr = (struct ieee80211_hdr *) skb->data;
1207
1208                /* for rx pkt statistics */
1209        psta = rtw_get_stainfo23a(&padapter->stapriv, hdr->addr2);
1210        if (psta) {
1211                psta->sta_stats.rx_mgnt_pkts++;
1212
1213                if (ieee80211_is_beacon(hdr->frame_control))
1214                        psta->sta_stats.rx_beacon_pkts++;
1215                else if (ieee80211_is_probe_req(hdr->frame_control))
1216                        psta->sta_stats.rx_probereq_pkts++;
1217                else if (ieee80211_is_probe_resp(hdr->frame_control)) {
1218                        if (ether_addr_equal(padapter->eeprompriv.mac_addr,
1219                                    hdr->addr1))
1220                                psta->sta_stats.rx_probersp_pkts++;
1221                        else if (is_broadcast_ether_addr(hdr->addr1) ||
1222                                 is_multicast_ether_addr(hdr->addr1))
1223                                psta->sta_stats.rx_probersp_bm_pkts++;
1224                        else
1225                                psta->sta_stats.rx_probersp_uo_pkts++;
1226                }
1227        }
1228
1229        mgt_dispatcher23a(padapter, precv_frame);
1230
1231        return _SUCCESS;
1232}
1233
1234static int validate_recv_data_frame(struct rtw_adapter *adapter,
1235                                    struct recv_frame *precv_frame)
1236{
1237        u8 bretry;
1238        u8 *psa, *pda;
1239        struct sta_info *psta = NULL;
1240        struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
1241        struct security_priv *psecuritypriv = &adapter->securitypriv;
1242        int ret = _SUCCESS;
1243        struct sk_buff *skb = precv_frame->pkt;
1244        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1245
1246
1247
1248        bretry = ieee80211_has_retry(hdr->frame_control);
1249        pda = ieee80211_get_DA(hdr);
1250        psa = ieee80211_get_SA(hdr);
1251
1252        ether_addr_copy(pattrib->dst, pda);
1253        ether_addr_copy(pattrib->src, psa);
1254
1255        switch (hdr->frame_control &
1256                cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) {
1257        case cpu_to_le16(0):
1258                ether_addr_copy(pattrib->bssid, hdr->addr3);
1259                ether_addr_copy(pattrib->ra, pda);
1260                ether_addr_copy(pattrib->ta, psa);
1261                ret = sta2sta_data_frame(adapter, precv_frame, &psta);
1262                break;
1263
1264        case cpu_to_le16(IEEE80211_FCTL_FROMDS):
1265                ether_addr_copy(pattrib->bssid, hdr->addr2);
1266                ether_addr_copy(pattrib->ra, pda);
1267                ether_addr_copy(pattrib->ta, hdr->addr2);
1268                ret = ap2sta_data_frame(adapter, precv_frame, &psta);
1269                break;
1270
1271        case cpu_to_le16(IEEE80211_FCTL_TODS):
1272                ether_addr_copy(pattrib->bssid, hdr->addr1);
1273                ether_addr_copy(pattrib->ra, hdr->addr1);
1274                ether_addr_copy(pattrib->ta, psa);
1275                ret = sta2ap_data_frame(adapter, precv_frame, &psta);
1276                break;
1277
1278        case cpu_to_le16(IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS):
1279                /*
1280                 * There is no BSSID in this case, but the driver has been
1281                 * using addr1 so far, so keep it for now.
1282                 */
1283                ether_addr_copy(pattrib->bssid, hdr->addr1);
1284                ether_addr_copy(pattrib->ra, hdr->addr1);
1285                ether_addr_copy(pattrib->ta, hdr->addr2);
1286                ret = _FAIL;
1287                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_, "case 3\n");
1288                break;
1289        }
1290
1291        if ((ret == _FAIL) || (ret == RTW_RX_HANDLED))
1292                goto exit;
1293
1294        if (!psta) {
1295                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1296                         "after to_fr_ds_chk; psta == NULL\n");
1297                ret = _FAIL;
1298                goto exit;
1299        }
1300
1301        /* psta->rssi = prxcmd->rssi; */
1302        /* psta->signal_quality = prxcmd->sq; */
1303        precv_frame->psta = psta;
1304
1305        pattrib->hdrlen = sizeof(struct ieee80211_hdr_3addr);
1306        if (ieee80211_has_a4(hdr->frame_control))
1307                pattrib->hdrlen += ETH_ALEN;
1308
1309        /* parsing QC field */
1310        if (pattrib->qos == 1) {
1311                __le16 *qptr = (__le16 *)ieee80211_get_qos_ctl(hdr);
1312                u16 qos_ctrl = le16_to_cpu(*qptr);
1313
1314                pattrib->priority = qos_ctrl & IEEE80211_QOS_CTL_TID_MASK;
1315                pattrib->ack_policy = (qos_ctrl >> 5) & 3;
1316                pattrib->amsdu =
1317                        (qos_ctrl & IEEE80211_QOS_CTL_A_MSDU_PRESENT) >> 7;
1318                pattrib->hdrlen += IEEE80211_QOS_CTL_LEN;
1319
1320                if (pattrib->priority != 0 && pattrib->priority != 3) {
1321                        adapter->recvpriv.bIsAnyNonBEPkts = true;
1322                }
1323        } else {
1324                pattrib->priority = 0;
1325                pattrib->ack_policy = 0;
1326                pattrib->amsdu = 0;
1327        }
1328
1329        if (pattrib->order) { /* HT-CTRL 11n */
1330                pattrib->hdrlen += 4;
1331        }
1332
1333        precv_frame->preorder_ctrl = &psta->recvreorder_ctrl[pattrib->priority];
1334
1335        /*  decache, drop duplicate recv packets */
1336        if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
1337            _FAIL) {
1338                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1339                         "decache : drop pkt\n");
1340                ret = _FAIL;
1341                goto exit;
1342        }
1343
1344        if (pattrib->privacy) {
1345                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1346                         "validate_recv_data_frame:pattrib->privacy =%x\n",
1347                         pattrib->privacy);
1348                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1349                         "^^^^^^^^^^^is_multicast_ether_addr(pattrib->ra(0x%02x)) =%d^^^^^^^^^^^^^^^6\n",
1350                         pattrib->ra[0],
1351                         is_multicast_ether_addr(pattrib->ra));
1352
1353                GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
1354                               is_multicast_ether_addr(pattrib->ra));
1355
1356                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1357                         "pattrib->encrypt =%d\n", pattrib->encrypt);
1358
1359                switch (pattrib->encrypt) {
1360                case WLAN_CIPHER_SUITE_WEP40:
1361                case WLAN_CIPHER_SUITE_WEP104:
1362                        pattrib->iv_len = IEEE80211_WEP_IV_LEN;
1363                        pattrib->icv_len = IEEE80211_WEP_ICV_LEN;
1364                        break;
1365                case WLAN_CIPHER_SUITE_TKIP:
1366                        pattrib->iv_len = IEEE80211_TKIP_IV_LEN;
1367                        pattrib->icv_len = IEEE80211_TKIP_ICV_LEN;
1368                        break;
1369                case WLAN_CIPHER_SUITE_CCMP:
1370                        pattrib->iv_len = IEEE80211_CCMP_HDR_LEN;
1371                        pattrib->icv_len = IEEE80211_CCMP_MIC_LEN;
1372                        break;
1373                default:
1374                        pattrib->iv_len = 0;
1375                        pattrib->icv_len = 0;
1376                        break;
1377                }
1378        } else {
1379                pattrib->encrypt = 0;
1380                pattrib->iv_len = 0;
1381                pattrib->icv_len = 0;
1382        }
1383
1384exit:
1385
1386
1387
1388        return ret;
1389}
1390
1391static void dump_rx_pkt(struct sk_buff *skb, u16 type, int level)
1392{
1393        int i;
1394        u8 *ptr;
1395
1396        if ((level == 1) ||
1397            ((level == 2) && (type == IEEE80211_FTYPE_MGMT)) ||
1398            ((level == 3) && (type == IEEE80211_FTYPE_DATA))) {
1399
1400                ptr = skb->data;
1401
1402                DBG_8723A("#############################\n");
1403
1404                for (i = 0; i < 64; i = i + 8)
1405                        DBG_8723A("%02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X:\n",
1406                                  *(ptr + i), *(ptr + i + 1), *(ptr + i + 2),
1407                                  *(ptr + i + 3), *(ptr + i + 4),
1408                                  *(ptr + i + 5), *(ptr + i + 6),
1409                                  *(ptr + i + 7));
1410                DBG_8723A("#############################\n");
1411        }
1412}
1413
1414static int validate_recv_frame(struct rtw_adapter *adapter,
1415                               struct recv_frame *precv_frame)
1416{
1417        /* shall check frame subtype, to / from ds, da, bssid */
1418
1419        /* then call check if rx seq/frag. duplicated. */
1420        u8 type;
1421        u8 subtype;
1422        int retval = _SUCCESS;
1423        struct rx_pkt_attrib *pattrib = & precv_frame->attrib;
1424        struct sk_buff *skb = precv_frame->pkt;
1425        struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1426        u8 ver;
1427        u8 bDumpRxPkt;
1428        u16 seq_ctrl, fctl;
1429
1430        fctl = le16_to_cpu(hdr->frame_control);
1431        ver = fctl & IEEE80211_FCTL_VERS;
1432        type = fctl & IEEE80211_FCTL_FTYPE;
1433        subtype = fctl & IEEE80211_FCTL_STYPE;
1434
1435        /* add version chk */
1436        if (ver != 0) {
1437                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1438                         "validate_recv_data_frame fail! (ver!= 0)\n");
1439                retval = _FAIL;
1440                goto exit;
1441        }
1442
1443        seq_ctrl = le16_to_cpu(hdr->seq_ctrl);
1444        pattrib->frag_num = seq_ctrl & IEEE80211_SCTL_FRAG;
1445        pattrib->seq_num = seq_ctrl >> 4;
1446
1447        pattrib->pw_save = ieee80211_has_pm(hdr->frame_control);
1448        pattrib->mfrag = ieee80211_has_morefrags(hdr->frame_control);
1449        pattrib->mdata = ieee80211_has_moredata(hdr->frame_control);
1450        pattrib->privacy = ieee80211_has_protected(hdr->frame_control);
1451        pattrib->order = ieee80211_has_order(hdr->frame_control);
1452
1453        GetHalDefVar8192CUsb(adapter, HAL_DEF_DBG_DUMP_RXPKT, &bDumpRxPkt);
1454
1455        if (unlikely(bDumpRxPkt == 1))
1456                dump_rx_pkt(skb, type, bDumpRxPkt);
1457
1458        switch (type) {
1459        case IEEE80211_FTYPE_MGMT:
1460                retval = validate_recv_mgnt_frame(adapter, precv_frame);
1461                if (retval == _FAIL) {
1462                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1463                                 "validate_recv_mgnt_frame fail\n");
1464                }
1465                retval = _FAIL; /*  only data frame return _SUCCESS */
1466                break;
1467        case IEEE80211_FTYPE_CTL:
1468                retval = validate_recv_ctrl_frame(adapter, precv_frame);
1469                if (retval == _FAIL) {
1470                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1471                                 "validate_recv_ctrl_frame fail\n");
1472                }
1473                retval = _FAIL; /*  only data frame return _SUCCESS */
1474                break;
1475        case IEEE80211_FTYPE_DATA:
1476                pattrib->qos = (subtype & IEEE80211_STYPE_QOS_DATA) ? 1 : 0;
1477                retval = validate_recv_data_frame(adapter, precv_frame);
1478                if (retval == _FAIL) {
1479                        struct recv_priv *precvpriv = &adapter->recvpriv;
1480
1481                        precvpriv->rx_drop++;
1482                }
1483                break;
1484        default:
1485                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1486                         "validate_recv_data_frame fail! type = 0x%x\n", type);
1487                retval = _FAIL;
1488                break;
1489        }
1490
1491exit:
1492        return retval;
1493}
1494
1495/* remove the wlanhdr and add the eth_hdr */
1496
1497static int wlanhdr_to_ethhdr (struct recv_frame *precvframe)
1498{
1499        u16     eth_type, len, hdrlen;
1500        u8      bsnaphdr;
1501        u8      *psnap;
1502        struct rtw_adapter *adapter = precvframe->adapter;
1503        struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
1504
1505        struct sk_buff *skb = precvframe->pkt;
1506        u8 *ptr;
1507        struct rx_pkt_attrib *pattrib = &precvframe->attrib;
1508
1509
1510
1511        ptr = skb->data;
1512        hdrlen = pattrib->hdrlen;
1513        psnap = ptr + hdrlen;
1514        eth_type = (psnap[6] << 8) | psnap[7];
1515        /* convert hdr + possible LLC headers into Ethernet header */
1516        /* eth_type = (psnap_type[0] << 8) | psnap_type[1]; */
1517        if ((ether_addr_equal(psnap, rfc1042_header) &&
1518             eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
1519            ether_addr_equal(psnap, bridge_tunnel_header)) {
1520                /* remove RFC1042 or Bridge-Tunnel encapsulation
1521                   and replace EtherType */
1522                bsnaphdr = true;
1523                hdrlen += SNAP_SIZE;
1524        } else {
1525                /* Leave Ethernet header part of hdr and full payload */
1526                bsnaphdr = false;
1527                eth_type = (psnap[0] << 8) | psnap[1];
1528        }
1529
1530        len = skb->len - hdrlen;
1531
1532        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1533                 "=== pattrib->hdrlen: %x,  pattrib->iv_len:%x ===\n",
1534                 pattrib->hdrlen,  pattrib->iv_len);
1535
1536        pattrib->eth_type = eth_type;
1537        if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
1538                ptr += hdrlen;
1539                *ptr = 0x87;
1540                *(ptr + 1) = 0x12;
1541
1542                eth_type = 0x8712;
1543                /*  append rx status for mp test packets */
1544
1545                ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) + 2) - 24);
1546                memcpy(ptr, skb->head, 24);
1547                ptr += 24;
1548        } else {
1549                ptr = skb_pull(skb, (hdrlen - sizeof(struct ethhdr) +
1550                                     (bsnaphdr ? 2:0)));
1551        }
1552
1553        ether_addr_copy(ptr, pattrib->dst);
1554        ether_addr_copy(ptr + ETH_ALEN, pattrib->src);
1555
1556        if (!bsnaphdr) {
1557                len = htons(len);
1558                memcpy(ptr + 12, &len, 2);
1559        }
1560
1561
1562        return _SUCCESS;
1563}
1564
1565/* perform defrag */
1566struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1567                                    struct rtw_queue *defrag_q);
1568struct recv_frame *recvframe_defrag(struct rtw_adapter *adapter,
1569                                    struct rtw_queue *defrag_q)
1570{
1571        struct list_head *plist, *phead, *ptmp;
1572        u8      *data, wlanhdr_offset;
1573        u8      curfragnum;
1574        struct recv_frame *pnfhdr;
1575        struct recv_frame *prframe, *pnextrframe;
1576        struct rtw_queue        *pfree_recv_queue;
1577        struct sk_buff *skb;
1578
1579
1580
1581        curfragnum = 0;
1582        pfree_recv_queue = &adapter->recvpriv.free_recv_queue;
1583
1584        phead = get_list_head(defrag_q);
1585        plist = phead->next;
1586        prframe = container_of(plist, struct recv_frame, list);
1587        list_del_init(&prframe->list);
1588        skb = prframe->pkt;
1589
1590        if (curfragnum != prframe->attrib.frag_num) {
1591                /* the first fragment number must be 0 */
1592                /* free the whole queue */
1593                rtw_free_recvframe23a(prframe);
1594                rtw_free_recvframe23a_queue(defrag_q);
1595
1596                return NULL;
1597        }
1598
1599        curfragnum++;
1600
1601        phead = get_list_head(defrag_q);
1602
1603        data = prframe->pkt->data;
1604
1605        list_for_each_safe(plist, ptmp, phead) {
1606                pnfhdr = container_of(plist, struct recv_frame, list);
1607                pnextrframe = (struct recv_frame *)pnfhdr;
1608                /* check the fragment sequence  (2nd ~n fragment frame) */
1609
1610                if (curfragnum != pnfhdr->attrib.frag_num) {
1611                        /* the fragment number must be increasing
1612                           (after decache) */
1613                        /* release the defrag_q & prframe */
1614                        rtw_free_recvframe23a(prframe);
1615                        rtw_free_recvframe23a_queue(defrag_q);
1616                        return NULL;
1617                }
1618
1619                curfragnum++;
1620
1621                /* copy the 2nd~n fragment frame's payload to the
1622                   first fragment */
1623                /* get the 2nd~last fragment frame's payload */
1624
1625                wlanhdr_offset = pnfhdr->attrib.hdrlen + pnfhdr->attrib.iv_len;
1626
1627                skb_pull(pnfhdr->pkt, wlanhdr_offset);
1628
1629                /* append  to first fragment frame's tail
1630                   (if privacy frame, pull the ICV) */
1631
1632                skb_trim(skb, skb->len - prframe->attrib.icv_len);
1633
1634                memcpy(skb_tail_pointer(skb), pnfhdr->pkt->data,
1635                       pnfhdr->pkt->len);
1636
1637                skb_put(skb, pnfhdr->pkt->len);
1638
1639                prframe->attrib.icv_len = pnfhdr->attrib.icv_len;
1640        }
1641
1642        /* free the defrag_q queue and return the prframe */
1643        rtw_free_recvframe23a_queue(defrag_q);
1644
1645        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1646                 "Performance defrag!!!!!\n");
1647
1648
1649
1650        return prframe;
1651}
1652
1653/* check if need to defrag, if needed queue the frame to defrag_q */
1654struct recv_frame *recvframe_chk_defrag23a(struct rtw_adapter *padapter,
1655                                        struct recv_frame *precv_frame)
1656{
1657        u8      ismfrag;
1658        u8      fragnum;
1659        u8      *psta_addr;
1660        struct recv_frame *pfhdr;
1661        struct sta_info *psta;
1662        struct sta_priv *pstapriv;
1663        struct list_head *phead;
1664        struct recv_frame *prtnframe = NULL;
1665        struct rtw_queue *pfree_recv_queue, *pdefrag_q;
1666
1667
1668
1669        pstapriv = &padapter->stapriv;
1670
1671        pfhdr = precv_frame;
1672
1673        pfree_recv_queue = &padapter->recvpriv.free_recv_queue;
1674
1675        /* need to define struct of wlan header frame ctrl */
1676        ismfrag = pfhdr->attrib.mfrag;
1677        fragnum = pfhdr->attrib.frag_num;
1678
1679        psta_addr = pfhdr->attrib.ta;
1680        psta = rtw_get_stainfo23a(pstapriv, psta_addr);
1681        if (!psta) {
1682                struct ieee80211_hdr *hdr =
1683                        (struct ieee80211_hdr *) pfhdr->pkt->data;
1684                if (!ieee80211_is_data(hdr->frame_control)) {
1685                        psta = rtw_get_bcmc_stainfo23a(padapter);
1686                        pdefrag_q = &psta->sta_recvpriv.defrag_q;
1687                } else
1688                        pdefrag_q = NULL;
1689        } else
1690                pdefrag_q = &psta->sta_recvpriv.defrag_q;
1691
1692        if ((ismfrag == 0) && (fragnum == 0)) {
1693                prtnframe = precv_frame;/* isn't a fragment frame */
1694        }
1695
1696        if (ismfrag == 1) {
1697                /* 0~(n-1) fragment frame */
1698                /* enqueue to defraf_g */
1699                if (pdefrag_q != NULL) {
1700                        if (fragnum == 0) {
1701                                /* the first fragment */
1702                                if (!list_empty(&pdefrag_q->queue)) {
1703                                        /* free current defrag_q */
1704                                        rtw_free_recvframe23a_queue(pdefrag_q);
1705                                }
1706                        }
1707
1708                        /* Then enqueue the 0~(n-1) fragment into the
1709                           defrag_q */
1710
1711                        /* spin_lock(&pdefrag_q->lock); */
1712                        phead = get_list_head(pdefrag_q);
1713                        list_add_tail(&pfhdr->list, phead);
1714                        /* spin_unlock(&pdefrag_q->lock); */
1715
1716                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1717                                 "Enqueuq: ismfrag = %d, fragnum = %d\n",
1718                                 ismfrag, fragnum);
1719
1720                        prtnframe = NULL;
1721
1722                } else {
1723                        /* can't find this ta's defrag_queue,
1724                           so free this recv_frame */
1725                        rtw_free_recvframe23a(precv_frame);
1726                        prtnframe = NULL;
1727                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1728                                 "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
1729                                 ismfrag, fragnum);
1730                }
1731        }
1732
1733        if ((ismfrag == 0) && (fragnum != 0)) {
1734                /* the last fragment frame */
1735                /* enqueue the last fragment */
1736                if (pdefrag_q != NULL) {
1737                        /* spin_lock(&pdefrag_q->lock); */
1738                        phead = get_list_head(pdefrag_q);
1739                        list_add_tail(&pfhdr->list, phead);
1740                        /* spin_unlock(&pdefrag_q->lock); */
1741
1742                        /* call recvframe_defrag to defrag */
1743                        RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1744                                 "defrag: ismfrag = %d, fragnum = %d\n",
1745                                 ismfrag, fragnum);
1746                        precv_frame = recvframe_defrag(padapter, pdefrag_q);
1747                        prtnframe = precv_frame;
1748                } else {
1749                        /* can't find this ta's defrag_queue,
1750                           so free this recv_frame */
1751                        rtw_free_recvframe23a(precv_frame);
1752                        prtnframe = NULL;
1753                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1754                                 "Free because pdefrag_q == NULL: ismfrag = %d, fragnum = %d\n",
1755                                 ismfrag, fragnum);
1756                }
1757
1758        }
1759
1760        if ((prtnframe != NULL) && (prtnframe->attrib.privacy)) {
1761                /* after defrag we must check tkip mic code */
1762                if (recvframe_chkmic(padapter,  prtnframe) == _FAIL) {
1763                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
1764                                 "recvframe_chkmic(padapter,  prtnframe) ==_FAIL\n");
1765                        rtw_free_recvframe23a(prtnframe);
1766                        prtnframe = NULL;
1767                }
1768        }
1769
1770
1771
1772        return prtnframe;
1773}
1774
1775int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe);
1776int amsdu_to_msdu(struct rtw_adapter *padapter, struct recv_frame *prframe)
1777{
1778        struct rx_pkt_attrib *pattrib;
1779        struct sk_buff *skb, *sub_skb;
1780        struct sk_buff_head skb_list;
1781
1782        pattrib = &prframe->attrib;
1783
1784        skb = prframe->pkt;
1785        skb_pull(skb, prframe->attrib.hdrlen);
1786        __skb_queue_head_init(&skb_list);
1787
1788        ieee80211_amsdu_to_8023s(skb, &skb_list, NULL, 0, 0, false);
1789
1790        while (!skb_queue_empty(&skb_list)) {
1791                sub_skb = __skb_dequeue(&skb_list);
1792
1793                sub_skb->protocol = eth_type_trans(sub_skb, padapter->pnetdev);
1794                sub_skb->dev = padapter->pnetdev;
1795
1796                sub_skb->ip_summed = CHECKSUM_NONE;
1797
1798                netif_rx(sub_skb);
1799        }
1800
1801        prframe->pkt = NULL;
1802        rtw_free_recvframe23a(prframe);
1803        return _SUCCESS;
1804}
1805
1806int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num);
1807int check_indicate_seq(struct recv_reorder_ctrl *preorder_ctrl, u16 seq_num)
1808{
1809        u8      wsize = preorder_ctrl->wsize_b;
1810        u16     wend = (preorder_ctrl->indicate_seq + wsize -1) & 0xFFF;
1811
1812        /*  Rx Reorder initialize condition. */
1813        if (preorder_ctrl->indicate_seq == 0xFFFF)
1814                preorder_ctrl->indicate_seq = seq_num;
1815
1816        /*  Drop out the packet which SeqNum is smaller than WinStart */
1817        if (SN_LESS(seq_num, preorder_ctrl->indicate_seq))
1818                return false;
1819
1820        /*  */
1821        /*  Sliding window manipulation. Conditions includes: */
1822        /*  1. Incoming SeqNum is equal to WinStart =>Window shift 1 */
1823        /*  2. Incoming SeqNum is larger than the WinEnd => Window shift N */
1824        /*  */
1825        if (SN_EQUAL(seq_num, preorder_ctrl->indicate_seq)) {
1826                preorder_ctrl->indicate_seq =
1827                        (preorder_ctrl->indicate_seq + 1) & 0xFFF;
1828        } else if (SN_LESS(wend, seq_num)) {
1829                /*  boundary situation, when seq_num cross 0xFFF */
1830                if (seq_num >= (wsize - 1))
1831                        preorder_ctrl->indicate_seq = seq_num + 1 -wsize;
1832                else
1833                        preorder_ctrl->indicate_seq = 0xFFF - (wsize - (seq_num + 1)) + 1;
1834        }
1835        return true;
1836}
1837
1838static int enqueue_reorder_recvframe23a(struct recv_reorder_ctrl *preorder_ctrl,
1839                                        struct recv_frame *prframe)
1840{
1841        struct rx_pkt_attrib *pattrib = &prframe->attrib;
1842        struct rtw_queue *ppending_recvframe_queue;
1843        struct list_head *phead, *plist, *ptmp;
1844        struct recv_frame *hdr;
1845        struct rx_pkt_attrib *pnextattrib;
1846
1847        ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1848        /* DbgPrint("+enqueue_reorder_recvframe23a()\n"); */
1849
1850        /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1851        /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1852
1853        phead = get_list_head(ppending_recvframe_queue);
1854
1855        list_for_each_safe(plist, ptmp, phead) {
1856                hdr = container_of(plist, struct recv_frame, list);
1857                pnextattrib = &hdr->attrib;
1858
1859                if (SN_LESS(pnextattrib->seq_num, pattrib->seq_num)) {
1860                        continue;
1861                } else if (SN_EQUAL(pnextattrib->seq_num, pattrib->seq_num)) {
1862                        /* Duplicate entry is found!! Do not insert current entry. */
1863
1864                        /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1865                        return false;
1866                } else {
1867                        break;
1868                }
1869
1870                /* DbgPrint("enqueue_reorder_recvframe23a():while\n"); */
1871        }
1872
1873        /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1874        /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1875
1876        list_del_init(&prframe->list);
1877
1878        list_add_tail(&prframe->list, plist);
1879
1880        /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1881        /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1882
1883        return true;
1884}
1885
1886int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1887                               struct recv_reorder_ctrl *preorder_ctrl,
1888                               int bforced);
1889int recv_indicatepkts_in_order(struct rtw_adapter *padapter,
1890                               struct recv_reorder_ctrl *preorder_ctrl,
1891                               int bforced)
1892{
1893        /* u8 bcancelled; */
1894        struct list_head *phead, *plist;
1895        struct recv_frame *prframe;
1896        struct rx_pkt_attrib *pattrib;
1897        /* u8 index = 0; */
1898        int bPktInBuf = false;
1899        struct recv_priv *precvpriv;
1900        struct rtw_queue *ppending_recvframe_queue;
1901
1902        precvpriv = &padapter->recvpriv;
1903        ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1904        /* DbgPrint("+recv_indicatepkts_in_order\n"); */
1905
1906        /* spin_lock_irqsave(&ppending_recvframe_queue->lock); */
1907        /* spin_lock_ex(&ppending_recvframe_queue->lock); */
1908
1909        phead = get_list_head(ppending_recvframe_queue);
1910        plist = phead->next;
1911
1912        /*  Handling some condition for forced indicate case. */
1913        if (bforced) {
1914                if (list_empty(phead)) {
1915                        /*  spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1916                        /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1917                        return true;
1918                }
1919
1920                prframe = container_of(plist, struct recv_frame, list);
1921                pattrib = &prframe->attrib;
1922                preorder_ctrl->indicate_seq = pattrib->seq_num;
1923        }
1924
1925        /*  Prepare indication list and indication. */
1926        /*  Check if there is any packet need indicate. */
1927        while (!list_empty(phead)) {
1928
1929                prframe = container_of(plist, struct recv_frame, list);
1930                pattrib = &prframe->attrib;
1931
1932                if (!SN_LESS(preorder_ctrl->indicate_seq, pattrib->seq_num)) {
1933                        RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1934                                 "recv_indicatepkts_in_order: indicate =%d seq =%d amsdu =%d\n",
1935                                 preorder_ctrl->indicate_seq,
1936                                 pattrib->seq_num, pattrib->amsdu);
1937
1938                        plist = plist->next;
1939                        list_del_init(&prframe->list);
1940
1941                        if (SN_EQUAL(preorder_ctrl->indicate_seq,
1942                                     pattrib->seq_num)) {
1943                                preorder_ctrl->indicate_seq =
1944                                        (preorder_ctrl->indicate_seq + 1)&0xFFF;
1945                        }
1946
1947                        if (!pattrib->amsdu) {
1948                                if ((padapter->bDriverStopped == false) &&
1949                                    (padapter->bSurpriseRemoved == false)) {
1950                                        rtw_recv_indicatepkt23a(padapter, prframe);
1951                                }
1952                        } else {
1953                                if (amsdu_to_msdu(padapter, prframe) !=
1954                                    _SUCCESS)
1955                                        rtw_free_recvframe23a(prframe);
1956                        }
1957
1958                        /* Update local variables. */
1959                        bPktInBuf = false;
1960
1961                } else {
1962                        bPktInBuf = true;
1963                        break;
1964                }
1965
1966                /* DbgPrint("recv_indicatepkts_in_order():while\n"); */
1967        }
1968
1969        /* spin_unlock_ex(&ppending_recvframe_queue->lock); */
1970        /* spin_unlock_irqrestore(&ppending_recvframe_queue->lock); */
1971
1972        return bPktInBuf;
1973}
1974
1975int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
1976                             struct recv_frame *prframe);
1977int recv_indicatepkt_reorder(struct rtw_adapter *padapter,
1978                             struct recv_frame *prframe)
1979{
1980        int retval = _SUCCESS;
1981        struct rx_pkt_attrib *pattrib;
1982        struct recv_reorder_ctrl *preorder_ctrl;
1983        struct rtw_queue *ppending_recvframe_queue;
1984
1985        pattrib = &prframe->attrib;
1986        preorder_ctrl = prframe->preorder_ctrl;
1987        ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
1988
1989        if (!pattrib->amsdu) {
1990                /* s1. */
1991                wlanhdr_to_ethhdr(prframe);
1992
1993                if ((pattrib->qos!= 1) || (pattrib->eth_type == ETH_P_ARP) ||
1994                    (pattrib->ack_policy != 0)) {
1995                        if ((padapter->bDriverStopped == false) &&
1996                            (padapter->bSurpriseRemoved == false)) {
1997                                RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
1998                                         "@@@@  recv_indicatepkt_reorder -recv_func recv_indicatepkt\n");
1999
2000                                rtw_recv_indicatepkt23a(padapter, prframe);
2001                                return _SUCCESS;
2002                        }
2003
2004                        return _FAIL;
2005                }
2006
2007                if (preorder_ctrl->enable == false) {
2008                        /* indicate this recv_frame */
2009                        preorder_ctrl->indicate_seq = pattrib->seq_num;
2010                        rtw_recv_indicatepkt23a(padapter, prframe);
2011
2012                        preorder_ctrl->indicate_seq =
2013                                (preorder_ctrl->indicate_seq + 1) % 4096;
2014                        return _SUCCESS;
2015                }
2016        } else {
2017                 /* temp filter -> means didn't support A-MSDUs in a A-MPDU */
2018                if (preorder_ctrl->enable == false) {
2019                        preorder_ctrl->indicate_seq = pattrib->seq_num;
2020                        retval = amsdu_to_msdu(padapter, prframe);
2021
2022                        preorder_ctrl->indicate_seq =
2023                                (preorder_ctrl->indicate_seq + 1) % 4096;
2024                        return retval;
2025                }
2026        }
2027
2028        spin_lock_bh(&ppending_recvframe_queue->lock);
2029
2030        RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2031                 "recv_indicatepkt_reorder: indicate =%d seq =%d\n",
2032                 preorder_ctrl->indicate_seq, pattrib->seq_num);
2033
2034        /* s2. check if winstart_b(indicate_seq) needs to been updated */
2035        if (!check_indicate_seq(preorder_ctrl, pattrib->seq_num)) {
2036                goto _err_exit;
2037        }
2038
2039        /* s3. Insert all packet into Reorder Queue to maintain its ordering. */
2040        if (!enqueue_reorder_recvframe23a(preorder_ctrl, prframe)) {
2041                goto _err_exit;
2042        }
2043
2044        /* s4. */
2045        /*  Indication process. */
2046        /*  After Packet dropping and Sliding Window shifting as above,
2047            we can now just indicate the packets */
2048        /*  with the SeqNum smaller than latest WinStart and buffer
2049            other packets. */
2050        /*  */
2051        /*  For Rx Reorder condition: */
2052        /*  1. All packets with SeqNum smaller than WinStart => Indicate */
2053        /*  2. All packets with SeqNum larger than or equal to WinStart =>
2054            Buffer it. */
2055        /*  */
2056
2057        if (recv_indicatepkts_in_order(padapter, preorder_ctrl, false) == true) {
2058                mod_timer(&preorder_ctrl->reordering_ctrl_timer,
2059                          jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
2060                spin_unlock_bh(&ppending_recvframe_queue->lock);
2061        } else {
2062                spin_unlock_bh(&ppending_recvframe_queue->lock);
2063                del_timer_sync(&preorder_ctrl->reordering_ctrl_timer);
2064        }
2065        return _SUCCESS;
2066
2067_err_exit:
2068
2069        spin_unlock_bh(&ppending_recvframe_queue->lock);
2070        return _FAIL;
2071}
2072
2073void rtw_reordering_ctrl_timeout_handler23a(unsigned long pcontext)
2074{
2075        struct recv_reorder_ctrl *preorder_ctrl;
2076        struct rtw_adapter *padapter;
2077        struct rtw_queue *ppending_recvframe_queue;
2078
2079        preorder_ctrl = (struct recv_reorder_ctrl *)pcontext;
2080        padapter = preorder_ctrl->padapter;
2081        ppending_recvframe_queue = &preorder_ctrl->pending_recvframe_queue;
2082
2083        if (padapter->bDriverStopped || padapter->bSurpriseRemoved) {
2084                return;
2085        }
2086
2087        /* DBG_8723A("+rtw_reordering_ctrl_timeout_handler23a() =>\n"); */
2088
2089        spin_lock_bh(&ppending_recvframe_queue->lock);
2090
2091        if (recv_indicatepkts_in_order(padapter, preorder_ctrl, true) == true) {
2092                mod_timer(&preorder_ctrl->reordering_ctrl_timer,
2093                          jiffies + msecs_to_jiffies(REORDER_WAIT_TIME));
2094        }
2095
2096        spin_unlock_bh(&ppending_recvframe_queue->lock);
2097}
2098
2099int process_recv_indicatepkts(struct rtw_adapter *padapter,
2100                              struct recv_frame *prframe);
2101int process_recv_indicatepkts(struct rtw_adapter *padapter,
2102                              struct recv_frame *prframe)
2103{
2104        int retval = _SUCCESS;
2105        /* struct recv_priv *precvpriv = &padapter->recvpriv; */
2106        /* struct rx_pkt_attrib *pattrib = &prframe->attrib; */
2107        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2108        struct ht_priv *phtpriv = &pmlmepriv->htpriv;
2109
2110        if (phtpriv->ht_option == true) { /* B/G/N Mode */
2111                /* prframe->preorder_ctrl = &precvpriv->recvreorder_ctrl[pattrib->priority]; */
2112
2113                /*  including perform A-MPDU Rx Ordering Buffer Control */
2114                if (recv_indicatepkt_reorder(padapter, prframe) != _SUCCESS) {
2115                        if ((padapter->bDriverStopped == false) &&
2116                            (padapter->bSurpriseRemoved == false)) {
2117                                retval = _FAIL;
2118                                return retval;
2119                        }
2120                }
2121        } else { /* B/G mode */
2122                retval = wlanhdr_to_ethhdr(prframe);
2123                if (retval != _SUCCESS) {
2124                        RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2125                                 "wlanhdr_to_ethhdr: drop pkt\n");
2126                        return retval;
2127                }
2128
2129                if ((padapter->bDriverStopped == false) &&
2130                    (padapter->bSurpriseRemoved == false)) {
2131                        /* indicate this recv_frame */
2132                        RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2133                                 "@@@@ process_recv_indicatepkts- recv_func recv_indicatepkt\n");
2134                        rtw_recv_indicatepkt23a(padapter, prframe);
2135                } else {
2136                        RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2137                                 "@@@@ process_recv_indicatepkts- recv_func free_indicatepkt\n");
2138
2139                        RT_TRACE(_module_rtl871x_recv_c_, _drv_notice_,
2140                                 "recv_func:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n",
2141                                 padapter->bDriverStopped,
2142                                 padapter->bSurpriseRemoved);
2143                        retval = _FAIL;
2144                        return retval;
2145                }
2146
2147        }
2148
2149        return retval;
2150}
2151
2152static int recv_func_prehandle(struct rtw_adapter *padapter,
2153                               struct recv_frame *rframe)
2154{
2155        int ret = _SUCCESS;
2156
2157        /* check the frame crtl field and decache */
2158        ret = validate_recv_frame(padapter, rframe);
2159        if (ret != _SUCCESS) {
2160                RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
2161                         "recv_func: validate_recv_frame fail! drop pkt\n");
2162                rtw_free_recvframe23a(rframe);
2163                goto exit;
2164        }
2165
2166exit:
2167        return ret;
2168}
2169
2170static int recv_func_posthandle(struct rtw_adapter *padapter,
2171                                struct recv_frame *prframe)
2172{
2173        int ret = _SUCCESS;
2174        struct recv_frame *orig_prframe = prframe;
2175        struct recv_priv *precvpriv = &padapter->recvpriv;
2176
2177        /*  DATA FRAME */
2178        prframe = decryptor(padapter, prframe);
2179        if (prframe == NULL) {
2180                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2181                         "decryptor: drop pkt\n");
2182                ret = _FAIL;
2183                goto _recv_data_drop;
2184        }
2185
2186        prframe = recvframe_chk_defrag23a(padapter, prframe);
2187        if (!prframe) {
2188                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2189                         "recvframe_chk_defrag23a: drop pkt\n");
2190                goto _recv_data_drop;
2191        }
2192
2193        /*
2194         * Pull off crypto headers
2195         */
2196        if (prframe->attrib.iv_len > 0) {
2197                skb_pull(prframe->pkt, prframe->attrib.iv_len);
2198        }
2199
2200        if (prframe->attrib.icv_len > 0) {
2201                skb_trim(prframe->pkt,
2202                         prframe->pkt->len - prframe->attrib.icv_len);
2203        }
2204
2205        prframe = portctrl(padapter, prframe);
2206        if (!prframe) {
2207                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2208                         "portctrl: drop pkt\n");
2209                ret = _FAIL;
2210                goto _recv_data_drop;
2211        }
2212
2213        count_rx_stats(padapter, prframe, NULL);
2214
2215        ret = process_recv_indicatepkts(padapter, prframe);
2216        if (ret != _SUCCESS) {
2217                RT_TRACE(_module_rtl871x_recv_c_, _drv_err_,
2218                         "recv_func: process_recv_indicatepkts fail!\n");
2219                rtw_free_recvframe23a(orig_prframe);/* free this recv_frame */
2220                goto _recv_data_drop;
2221        }
2222        return ret;
2223
2224_recv_data_drop:
2225        precvpriv->rx_drop++;
2226        return ret;
2227}
2228
2229int rtw_recv_entry23a(struct recv_frame *rframe)
2230{
2231        int ret, r;
2232        struct rtw_adapter *padapter = rframe->adapter;
2233        struct rx_pkt_attrib *prxattrib = &rframe->attrib;
2234        struct recv_priv *recvpriv = &padapter->recvpriv;
2235        struct security_priv *psecuritypriv = &padapter->securitypriv;
2236        struct mlme_priv *mlmepriv = &padapter->mlmepriv;
2237
2238        /* check if need to handle uc_swdec_pending_queue*/
2239        if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2240            psecuritypriv->busetkipkey) {
2241                struct recv_frame *pending_frame;
2242
2243                while ((pending_frame = rtw_alloc_recvframe23a(&padapter->recvpriv.uc_swdec_pending_queue))) {
2244                        r = recv_func_posthandle(padapter, pending_frame);
2245                        if (r == _SUCCESS)
2246                                DBG_8723A("%s: dequeue uc_swdec_pending_queue\n", __func__);
2247                }
2248        }
2249
2250        ret = recv_func_prehandle(padapter, rframe);
2251
2252        if (ret == _SUCCESS) {
2253                /* check if need to enqueue into uc_swdec_pending_queue*/
2254                if (check_fwstate(mlmepriv, WIFI_STATION_STATE) &&
2255                    !is_multicast_ether_addr(prxattrib->ra) &&
2256                    prxattrib->encrypt > 0 &&
2257                    (prxattrib->bdecrypted == 0) &&
2258                    !is_wep_enc(psecuritypriv->dot11PrivacyAlgrthm) &&
2259                    !psecuritypriv->busetkipkey) {
2260                        rtw_enqueue_recvframe23a(rframe, &padapter->recvpriv.uc_swdec_pending_queue);
2261                        DBG_8723A("%s: no key, enqueue uc_swdec_pending_queue\n", __func__);
2262                        goto exit;
2263                }
2264
2265                ret = recv_func_posthandle(padapter, rframe);
2266
2267                recvpriv->rx_pkts++;
2268        }
2269
2270exit:
2271        return ret;
2272}
2273
2274void rtw_signal_stat_timer_hdl23a(unsigned long data)
2275{
2276        struct rtw_adapter *adapter = (struct rtw_adapter *)data;
2277        struct recv_priv *recvpriv = &adapter->recvpriv;
2278
2279        u32 tmp_s, tmp_q;
2280        u8 avg_signal_strength = 0;
2281        u8 avg_signal_qual = 0;
2282        u32 num_signal_strength = 0;
2283        u32 num_signal_qual = 0;
2284        u8 _alpha = 3;  /* this value is based on converging_constant = 5000 */
2285                        /* and sampling_interval = 1000 */
2286
2287        if (recvpriv->signal_strength_data.update_req == 0) {
2288                /*  update_req is clear, means we got rx */
2289                avg_signal_strength = recvpriv->signal_strength_data.avg_val;
2290                num_signal_strength = recvpriv->signal_strength_data.total_num;
2291                /*  after avg_vals are acquired, we can re-stat */
2292                /* the signal values */
2293                recvpriv->signal_strength_data.update_req = 1;
2294        }
2295
2296        if (recvpriv->signal_qual_data.update_req == 0) {
2297                /*  update_req is clear, means we got rx */
2298                avg_signal_qual = recvpriv->signal_qual_data.avg_val;
2299                num_signal_qual = recvpriv->signal_qual_data.total_num;
2300                /*  after avg_vals are acquired, we can re-stat */
2301                /*the signal values */
2302                recvpriv->signal_qual_data.update_req = 1;
2303        }
2304
2305        /* update value of signal_strength, rssi, signal_qual */
2306        if (!check_fwstate(&adapter->mlmepriv, _FW_UNDER_SURVEY)) {
2307                tmp_s = avg_signal_strength + (_alpha - 1) *
2308                         recvpriv->signal_strength;
2309                if (tmp_s %_alpha)
2310                        tmp_s = tmp_s / _alpha + 1;
2311                else
2312                        tmp_s = tmp_s / _alpha;
2313                if (tmp_s > 100)
2314                        tmp_s = 100;
2315
2316                tmp_q = avg_signal_qual + (_alpha - 1) * recvpriv->signal_qual;
2317                if (tmp_q %_alpha)
2318                        tmp_q = tmp_q / _alpha + 1;
2319                else
2320                        tmp_q = tmp_q / _alpha;
2321                if (tmp_q > 100)
2322                        tmp_q = 100;
2323
2324                recvpriv->signal_strength = tmp_s;
2325                recvpriv->signal_qual = tmp_q;
2326
2327                DBG_8723A("%s signal_strength:%3u, signal_qual:%3u, "
2328                          "num_signal_strength:%u, num_signal_qual:%u\n",
2329                          __func__, recvpriv->signal_strength,
2330                          recvpriv->signal_qual, num_signal_strength,
2331                          num_signal_qual);
2332        }
2333
2334        rtw_set_signal_stat_timer(recvpriv);
2335}
2336