linux/drivers/staging/rtl8723bs/core/rtw_xmit.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5 *
   6 ******************************************************************************/
   7#include <drv_types.h>
   8#include <rtw_debug.h>
   9
  10static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
  11static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
  12
  13static void _init_txservq(struct tx_servq *ptxservq)
  14{
  15        INIT_LIST_HEAD(&ptxservq->tx_pending);
  16        _rtw_init_queue(&ptxservq->sta_pending);
  17        ptxservq->qcnt = 0;
  18}
  19
  20void _rtw_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
  21{
  22        memset((unsigned char *)psta_xmitpriv, 0, sizeof(struct sta_xmit_priv));
  23
  24        spin_lock_init(&psta_xmitpriv->lock);
  25
  26        _init_txservq(&psta_xmitpriv->be_q);
  27        _init_txservq(&psta_xmitpriv->bk_q);
  28        _init_txservq(&psta_xmitpriv->vi_q);
  29        _init_txservq(&psta_xmitpriv->vo_q);
  30        INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
  31        INIT_LIST_HEAD(&psta_xmitpriv->apsd);
  32}
  33
  34s32 _rtw_init_xmit_priv(struct xmit_priv *pxmitpriv, struct adapter *padapter)
  35{
  36        int i;
  37        struct xmit_buf *pxmitbuf;
  38        struct xmit_frame *pxframe;
  39        signed int      res = _SUCCESS;
  40
  41        spin_lock_init(&pxmitpriv->lock);
  42        spin_lock_init(&pxmitpriv->lock_sctx);
  43        init_completion(&pxmitpriv->xmit_comp);
  44        init_completion(&pxmitpriv->terminate_xmitthread_comp);
  45
  46        /*
  47         * Please insert all the queue initializaiton using _rtw_init_queue below
  48         */
  49
  50        pxmitpriv->adapter = padapter;
  51
  52        _rtw_init_queue(&pxmitpriv->be_pending);
  53        _rtw_init_queue(&pxmitpriv->bk_pending);
  54        _rtw_init_queue(&pxmitpriv->vi_pending);
  55        _rtw_init_queue(&pxmitpriv->vo_pending);
  56        _rtw_init_queue(&pxmitpriv->bm_pending);
  57
  58        _rtw_init_queue(&pxmitpriv->free_xmit_queue);
  59
  60        /*
  61         * Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
  62         * and initialize free_xmit_frame below.
  63         * Please also apply  free_txobj to link_up all the xmit_frames...
  64         */
  65
  66        pxmitpriv->pallocated_frame_buf = vzalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4);
  67
  68        if (!pxmitpriv->pallocated_frame_buf) {
  69                pxmitpriv->pxmit_frame_buf = NULL;
  70                res = _FAIL;
  71                goto exit;
  72        }
  73        pxmitpriv->pxmit_frame_buf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_frame_buf), 4);
  74
  75        pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
  76
  77        for (i = 0; i < NR_XMITFRAME; i++) {
  78                INIT_LIST_HEAD(&pxframe->list);
  79
  80                pxframe->padapter = padapter;
  81                pxframe->frame_tag = NULL_FRAMETAG;
  82
  83                pxframe->pkt = NULL;
  84
  85                pxframe->buf_addr = NULL;
  86                pxframe->pxmitbuf = NULL;
  87
  88                list_add_tail(&pxframe->list,
  89                              &pxmitpriv->free_xmit_queue.queue);
  90
  91                pxframe++;
  92        }
  93
  94        pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
  95
  96        pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
  97
  98        /* init xmit_buf */
  99        _rtw_init_queue(&pxmitpriv->free_xmitbuf_queue);
 100        _rtw_init_queue(&pxmitpriv->pending_xmitbuf_queue);
 101
 102        pxmitpriv->pallocated_xmitbuf = vzalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4);
 103
 104        if (!pxmitpriv->pallocated_xmitbuf) {
 105                res = _FAIL;
 106                goto exit;
 107        }
 108
 109        pxmitpriv->pxmitbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmitbuf), 4);
 110
 111        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 112
 113        for (i = 0; i < NR_XMITBUFF; i++) {
 114                INIT_LIST_HEAD(&pxmitbuf->list);
 115
 116                pxmitbuf->priv_data = NULL;
 117                pxmitbuf->padapter = padapter;
 118                pxmitbuf->buf_tag = XMITBUF_DATA;
 119
 120                /* Tx buf allocation may fail sometimes, so sleep and retry. */
 121                res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), true);
 122                if (res == _FAIL) {
 123                        msleep(10);
 124                        res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), true);
 125                        if (res == _FAIL)
 126                                goto exit;
 127                }
 128
 129                pxmitbuf->phead = pxmitbuf->pbuf;
 130                pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMITBUF_SZ;
 131                pxmitbuf->len = 0;
 132                pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
 133
 134                pxmitbuf->flags = XMIT_VO_QUEUE;
 135
 136                list_add_tail(&pxmitbuf->list,
 137                              &pxmitpriv->free_xmitbuf_queue.queue);
 138                #ifdef DBG_XMIT_BUF
 139                pxmitbuf->no = i;
 140                #endif
 141
 142                pxmitbuf++;
 143        }
 144
 145        pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
 146
 147        /* init xframe_ext queue,  the same count as extbuf  */
 148        _rtw_init_queue(&pxmitpriv->free_xframe_ext_queue);
 149
 150        pxmitpriv->xframe_ext_alloc_addr = vzalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_frame) + 4);
 151
 152        if (!pxmitpriv->xframe_ext_alloc_addr) {
 153                pxmitpriv->xframe_ext = NULL;
 154                res = _FAIL;
 155                goto exit;
 156        }
 157        pxmitpriv->xframe_ext = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->xframe_ext_alloc_addr), 4);
 158        pxframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
 159
 160        for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
 161                INIT_LIST_HEAD(&pxframe->list);
 162
 163                pxframe->padapter = padapter;
 164                pxframe->frame_tag = NULL_FRAMETAG;
 165
 166                pxframe->pkt = NULL;
 167
 168                pxframe->buf_addr = NULL;
 169                pxframe->pxmitbuf = NULL;
 170
 171                pxframe->ext_tag = 1;
 172
 173                list_add_tail(&pxframe->list,
 174                              &pxmitpriv->free_xframe_ext_queue.queue);
 175
 176                pxframe++;
 177        }
 178        pxmitpriv->free_xframe_ext_cnt = NR_XMIT_EXTBUFF;
 179
 180        /*  Init xmit extension buff */
 181        _rtw_init_queue(&pxmitpriv->free_xmit_extbuf_queue);
 182
 183        pxmitpriv->pallocated_xmit_extbuf = vzalloc(NR_XMIT_EXTBUFF * sizeof(struct xmit_buf) + 4);
 184
 185        if (!pxmitpriv->pallocated_xmit_extbuf) {
 186                res = _FAIL;
 187                goto exit;
 188        }
 189
 190        pxmitpriv->pxmit_extbuf = (u8 *)N_BYTE_ALIGMENT((SIZE_PTR)(pxmitpriv->pallocated_xmit_extbuf), 4);
 191
 192        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
 193
 194        for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
 195                INIT_LIST_HEAD(&pxmitbuf->list);
 196
 197                pxmitbuf->priv_data = NULL;
 198                pxmitbuf->padapter = padapter;
 199                pxmitbuf->buf_tag = XMITBUF_MGNT;
 200
 201                res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ, true);
 202                if (res == _FAIL) {
 203                        res = _FAIL;
 204                        goto exit;
 205                }
 206
 207                pxmitbuf->phead = pxmitbuf->pbuf;
 208                pxmitbuf->pend = pxmitbuf->pbuf + MAX_XMIT_EXTBUF_SZ;
 209                pxmitbuf->len = 0;
 210                pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
 211
 212                list_add_tail(&pxmitbuf->list,
 213                              &pxmitpriv->free_xmit_extbuf_queue.queue);
 214                #ifdef DBG_XMIT_BUF_EXT
 215                pxmitbuf->no = i;
 216                #endif
 217                pxmitbuf++;
 218        }
 219
 220        pxmitpriv->free_xmit_extbuf_cnt = NR_XMIT_EXTBUFF;
 221
 222        for (i = 0; i < CMDBUF_MAX; i++) {
 223                pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
 224                if (pxmitbuf) {
 225                        INIT_LIST_HEAD(&pxmitbuf->list);
 226
 227                        pxmitbuf->priv_data = NULL;
 228                        pxmitbuf->padapter = padapter;
 229                        pxmitbuf->buf_tag = XMITBUF_CMD;
 230
 231                        res = rtw_os_xmit_resource_alloc(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, true);
 232                        if (res == _FAIL) {
 233                                res = _FAIL;
 234                                goto exit;
 235                        }
 236
 237                        pxmitbuf->phead = pxmitbuf->pbuf;
 238                        pxmitbuf->pend = pxmitbuf->pbuf + MAX_CMDBUF_SZ;
 239                        pxmitbuf->len = 0;
 240                        pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
 241                        pxmitbuf->alloc_sz = MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ;
 242                }
 243        }
 244
 245        res = rtw_alloc_hwxmits(padapter);
 246        if (res == _FAIL)
 247                goto exit;
 248        rtw_init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 249
 250        for (i = 0; i < 4; i++)
 251                pxmitpriv->wmm_para_seq[i] = i;
 252
 253        pxmitpriv->ack_tx = false;
 254        mutex_init(&pxmitpriv->ack_tx_mutex);
 255        rtw_sctx_init(&pxmitpriv->ack_tx_ops, 0);
 256
 257        rtw_hal_init_xmit_priv(padapter);
 258
 259exit:
 260        return res;
 261}
 262
 263void _rtw_free_xmit_priv(struct xmit_priv *pxmitpriv)
 264{
 265        int i;
 266        struct adapter *padapter = pxmitpriv->adapter;
 267        struct xmit_frame       *pxmitframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
 268        struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 269
 270        rtw_hal_free_xmit_priv(padapter);
 271
 272        if (!pxmitpriv->pxmit_frame_buf)
 273                return;
 274
 275        for (i = 0; i < NR_XMITFRAME; i++) {
 276                rtw_os_xmit_complete(padapter, pxmitframe);
 277
 278                pxmitframe++;
 279        }
 280
 281        for (i = 0; i < NR_XMITBUFF; i++) {
 282                rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ), true);
 283
 284                pxmitbuf++;
 285        }
 286
 287        vfree(pxmitpriv->pallocated_frame_buf);
 288        vfree(pxmitpriv->pallocated_xmitbuf);
 289
 290        /* free xframe_ext queue,  the same count as extbuf  */
 291        pxmitframe = (struct xmit_frame *)pxmitpriv->xframe_ext;
 292        if (pxmitframe) {
 293                for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
 294                        rtw_os_xmit_complete(padapter, pxmitframe);
 295                        pxmitframe++;
 296                }
 297        }
 298
 299        vfree(pxmitpriv->xframe_ext_alloc_addr);
 300
 301        /*  free xmit extension buff */
 302        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmit_extbuf;
 303        for (i = 0; i < NR_XMIT_EXTBUFF; i++) {
 304                rtw_os_xmit_resource_free(padapter, pxmitbuf, (MAX_XMIT_EXTBUF_SZ + XMITBUF_ALIGN_SZ), true);
 305
 306                pxmitbuf++;
 307        }
 308
 309        vfree(pxmitpriv->pallocated_xmit_extbuf);
 310
 311        for (i = 0; i < CMDBUF_MAX; i++) {
 312                pxmitbuf = &pxmitpriv->pcmd_xmitbuf[i];
 313                if (pxmitbuf)
 314                        rtw_os_xmit_resource_free(padapter, pxmitbuf, MAX_CMDBUF_SZ+XMITBUF_ALIGN_SZ, true);
 315        }
 316
 317        rtw_free_hwxmits(padapter);
 318
 319        mutex_destroy(&pxmitpriv->ack_tx_mutex);
 320}
 321
 322u8 query_ra_short_GI(struct sta_info *psta)
 323{
 324        u8 sgi = false, sgi_20m = false, sgi_40m = false;
 325
 326        sgi_20m = psta->htpriv.sgi_20m;
 327        sgi_40m = psta->htpriv.sgi_40m;
 328
 329        switch (psta->bw_mode) {
 330        case CHANNEL_WIDTH_40:
 331                sgi = sgi_40m;
 332                break;
 333        case CHANNEL_WIDTH_20:
 334        default:
 335                sgi = sgi_20m;
 336                break;
 337        }
 338
 339        return sgi;
 340}
 341
 342static void update_attrib_vcs_info(struct adapter *padapter, struct xmit_frame *pxmitframe)
 343{
 344        u32 sz;
 345        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 346        /* struct sta_info *psta = pattrib->psta; */
 347        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 348        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 349
 350        if (pattrib->nr_frags != 1)
 351                sz = padapter->xmitpriv.frag_len;
 352        else /* no frag */
 353                sz = pattrib->last_txcmdsz;
 354
 355        /*  (1) RTS_Threshold is compared to the MPDU, not MSDU. */
 356        /*  (2) If there are more than one frag in  this MSDU, only the first frag uses protection frame. */
 357        /* Other fragments are protected by previous fragment. */
 358        /* So we only need to check the length of first fragment. */
 359        if (pmlmeext->cur_wireless_mode < WIRELESS_11_24N  || padapter->registrypriv.wifi_spec) {
 360                if (sz > padapter->registrypriv.rts_thresh) {
 361                        pattrib->vcs_mode = RTS_CTS;
 362                } else {
 363                        if (pattrib->rtsen)
 364                                pattrib->vcs_mode = RTS_CTS;
 365                        else if (pattrib->cts2self)
 366                                pattrib->vcs_mode = CTS_TO_SELF;
 367                        else
 368                                pattrib->vcs_mode = NONE_VCS;
 369                }
 370        } else {
 371                while (true) {
 372                        /* IOT action */
 373                        if ((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS) && (pattrib->ampdu_en == true) &&
 374                                (padapter->securitypriv.dot11PrivacyAlgrthm == _AES_)) {
 375                                pattrib->vcs_mode = CTS_TO_SELF;
 376                                break;
 377                        }
 378
 379                        /* check ERP protection */
 380                        if (pattrib->rtsen || pattrib->cts2self) {
 381                                if (pattrib->rtsen)
 382                                        pattrib->vcs_mode = RTS_CTS;
 383                                else if (pattrib->cts2self)
 384                                        pattrib->vcs_mode = CTS_TO_SELF;
 385
 386                                break;
 387                        }
 388
 389                        /* check HT op mode */
 390                        if (pattrib->ht_en) {
 391                                u8 HTOpMode = pmlmeinfo->HT_protection;
 392
 393                                if ((pmlmeext->cur_bwmode && (HTOpMode == 2 || HTOpMode == 3)) ||
 394                                        (!pmlmeext->cur_bwmode && HTOpMode == 3)) {
 395                                        pattrib->vcs_mode = RTS_CTS;
 396                                        break;
 397                                }
 398                        }
 399
 400                        /* check rts */
 401                        if (sz > padapter->registrypriv.rts_thresh) {
 402                                pattrib->vcs_mode = RTS_CTS;
 403                                break;
 404                        }
 405
 406                        /* to do list: check MIMO power save condition. */
 407
 408                        /* check AMPDU aggregation for TXOP */
 409                        if (pattrib->ampdu_en == true) {
 410                                pattrib->vcs_mode = RTS_CTS;
 411                                break;
 412                        }
 413
 414                        pattrib->vcs_mode = NONE_VCS;
 415                        break;
 416                }
 417        }
 418
 419        /* for debug : force driver control vrtl_carrier_sense. */
 420        if (padapter->driver_vcs_en == 1)
 421                pattrib->vcs_mode = padapter->driver_vcs_type;
 422}
 423
 424static void update_attrib_phy_info(struct adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
 425{
 426        struct mlme_ext_priv *mlmeext = &padapter->mlmeextpriv;
 427
 428        pattrib->rtsen = psta->rtsen;
 429        pattrib->cts2self = psta->cts2self;
 430
 431        pattrib->mdata = 0;
 432        pattrib->eosp = 0;
 433        pattrib->triggered = 0;
 434        pattrib->ampdu_spacing = 0;
 435
 436        /* qos_en, ht_en, init rate, , bw, ch_offset, sgi */
 437        pattrib->qos_en = psta->qos_option;
 438
 439        pattrib->raid = psta->raid;
 440
 441        if (mlmeext->cur_bwmode < psta->bw_mode)
 442                pattrib->bwmode = mlmeext->cur_bwmode;
 443        else
 444                pattrib->bwmode = psta->bw_mode;
 445
 446        pattrib->sgi = query_ra_short_GI(psta);
 447
 448        pattrib->ldpc = psta->ldpc;
 449        pattrib->stbc = psta->stbc;
 450
 451        pattrib->ht_en = psta->htpriv.ht_option;
 452        pattrib->ch_offset = psta->htpriv.ch_offset;
 453        pattrib->ampdu_en = false;
 454
 455        if (padapter->driver_ampdu_spacing != 0xFF) /* driver control AMPDU Density for peer sta's rx */
 456                pattrib->ampdu_spacing = padapter->driver_ampdu_spacing;
 457        else
 458                pattrib->ampdu_spacing = psta->htpriv.rx_ampdu_min_spacing;
 459
 460        pattrib->retry_ctrl = false;
 461}
 462
 463static s32 update_attrib_sec_info(struct adapter *padapter, struct pkt_attrib *pattrib, struct sta_info *psta)
 464{
 465        signed int res = _SUCCESS;
 466        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 467        struct security_priv *psecuritypriv = &padapter->securitypriv;
 468        signed int bmcast = IS_MCAST(pattrib->ra);
 469
 470        memset(pattrib->dot118021x_UncstKey.skey,  0, 16);
 471        memset(pattrib->dot11tkiptxmickey.skey,  0, 16);
 472        pattrib->mac_id = psta->mac_id;
 473
 474        if (psta->ieee8021x_blocked == true) {
 475                pattrib->encrypt = 0;
 476
 477                if ((pattrib->ether_type != 0x888e) && (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false)) {
 478                        res = _FAIL;
 479                        goto exit;
 480                }
 481        } else {
 482                GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
 483
 484                switch (psecuritypriv->dot11AuthAlgrthm) {
 485                case dot11AuthAlgrthm_Open:
 486                case dot11AuthAlgrthm_Shared:
 487                case dot11AuthAlgrthm_Auto:
 488                        pattrib->key_idx = (u8)psecuritypriv->dot11PrivacyKeyIndex;
 489                        break;
 490                case dot11AuthAlgrthm_8021X:
 491                        if (bmcast)
 492                                pattrib->key_idx = (u8)psecuritypriv->dot118021XGrpKeyid;
 493                        else
 494                                pattrib->key_idx = 0;
 495                        break;
 496                default:
 497                        pattrib->key_idx = 0;
 498                        break;
 499                }
 500
 501                /* For WPS 1.0 WEP, driver should not encrypt EAPOL Packet for WPS handshake. */
 502                if (((pattrib->encrypt == _WEP40_) || (pattrib->encrypt == _WEP104_)) && (pattrib->ether_type == 0x888e))
 503                        pattrib->encrypt = _NO_PRIVACY_;
 504        }
 505
 506        switch (pattrib->encrypt) {
 507        case _WEP40_:
 508        case _WEP104_:
 509                pattrib->iv_len = 4;
 510                pattrib->icv_len = 4;
 511                WEP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
 512                break;
 513
 514        case _TKIP_:
 515                pattrib->iv_len = 8;
 516                pattrib->icv_len = 4;
 517
 518                if (psecuritypriv->busetkipkey == _FAIL) {
 519                        res = _FAIL;
 520                        goto exit;
 521                }
 522
 523                if (bmcast)
 524                        TKIP_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
 525                else
 526                        TKIP_IV(pattrib->iv, psta->dot11txpn, 0);
 527
 528                memcpy(pattrib->dot11tkiptxmickey.skey, psta->dot11tkiptxmickey.skey, 16);
 529
 530                break;
 531
 532        case _AES_:
 533
 534                pattrib->iv_len = 8;
 535                pattrib->icv_len = 8;
 536
 537                if (bmcast)
 538                        AES_IV(pattrib->iv, psta->dot11txpn, pattrib->key_idx);
 539                else
 540                        AES_IV(pattrib->iv, psta->dot11txpn, 0);
 541
 542                break;
 543
 544        default:
 545                pattrib->iv_len = 0;
 546                pattrib->icv_len = 0;
 547                break;
 548        }
 549
 550        if (pattrib->encrypt > 0)
 551                memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
 552
 553        if (pattrib->encrypt &&
 554                ((padapter->securitypriv.sw_encrypt) || (!psecuritypriv->hw_decrypted)))
 555                pattrib->bswenc = true;
 556        else
 557                pattrib->bswenc = false;
 558
 559exit:
 560
 561        return res;
 562}
 563
 564u8 qos_acm(u8 acm_mask, u8 priority)
 565{
 566        switch (priority) {
 567        case 0:
 568        case 3:
 569                if (acm_mask & BIT(1))
 570                        priority = 1;
 571                break;
 572        case 1:
 573        case 2:
 574                break;
 575        case 4:
 576        case 5:
 577                if (acm_mask & BIT(2))
 578                        priority = 0;
 579                break;
 580        case 6:
 581        case 7:
 582                if (acm_mask & BIT(3))
 583                        priority = 5;
 584                break;
 585        default:
 586                break;
 587        }
 588
 589        return priority;
 590}
 591
 592static void set_qos(struct pkt_file *ppktfile, struct pkt_attrib *pattrib)
 593{
 594        struct ethhdr etherhdr;
 595        struct iphdr ip_hdr;
 596        s32 UserPriority = 0;
 597
 598        _rtw_open_pktfile(ppktfile->pkt, ppktfile);
 599        _rtw_pktfile_read(ppktfile, (unsigned char *)&etherhdr, ETH_HLEN);
 600
 601        /*  get UserPriority from IP hdr */
 602        if (pattrib->ether_type == 0x0800) {
 603                _rtw_pktfile_read(ppktfile, (u8 *)&ip_hdr, sizeof(ip_hdr));
 604                UserPriority = ip_hdr.tos >> 5;
 605        }
 606        pattrib->priority = UserPriority;
 607        pattrib->hdrlen = WLAN_HDR_A3_QOS_LEN;
 608        pattrib->subtype = WIFI_QOS_DATA_TYPE;
 609}
 610
 611static s32 update_attrib(struct adapter *padapter, struct sk_buff *pkt, struct pkt_attrib *pattrib)
 612{
 613        struct pkt_file pktfile;
 614        struct sta_info *psta = NULL;
 615        struct ethhdr etherhdr;
 616
 617        signed int bmcast;
 618        struct sta_priv *pstapriv = &padapter->stapriv;
 619        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 620        struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 621        signed int res = _SUCCESS;
 622
 623        _rtw_open_pktfile(pkt, &pktfile);
 624        _rtw_pktfile_read(&pktfile, (u8 *)&etherhdr, ETH_HLEN);
 625
 626        pattrib->ether_type = ntohs(etherhdr.h_proto);
 627
 628        memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
 629        memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
 630
 631        if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
 632                (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
 633                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 634                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 635        } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 636                memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
 637                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 638        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 639                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 640                memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
 641        }
 642
 643        pattrib->pktlen = pktfile.pkt_len;
 644
 645        if (pattrib->ether_type == ETH_P_IP) {
 646                /*  The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time */
 647                /*  to prevent DHCP protocol fail */
 648
 649                u8 tmp[24];
 650
 651                _rtw_pktfile_read(&pktfile, &tmp[0], 24);
 652
 653                pattrib->dhcp_pkt = 0;
 654                if (pktfile.pkt_len > 282) {/* MINIMUM_DHCP_PACKET_SIZE) { */
 655                        if (pattrib->ether_type == ETH_P_IP) {/*  IP header */
 656                                if (((tmp[21] == 68) && (tmp[23] == 67)) ||
 657                                        ((tmp[21] == 67) && (tmp[23] == 68))) {
 658                                        /*  68 : UDP BOOTP client */
 659                                        /*  67 : UDP BOOTP server */
 660                                        pattrib->dhcp_pkt = 1;
 661                                }
 662                        }
 663                }
 664
 665                /* for parsing ICMP pakcets */
 666                {
 667                        struct iphdr *piphdr = (struct iphdr *)tmp;
 668
 669                        pattrib->icmp_pkt = 0;
 670                        if (piphdr->protocol == 0x1) /*  protocol type in ip header 0x1 is ICMP */
 671                                pattrib->icmp_pkt = 1;
 672                }
 673        } else if (pattrib->ether_type == 0x888e) {
 674                netdev_dbg(padapter->pnetdev, "send eapol packet\n");
 675        }
 676
 677        if ((pattrib->ether_type == 0x888e) || (pattrib->dhcp_pkt == 1))
 678                rtw_set_scan_deny(padapter, 3000);
 679
 680        /*  If EAPOL , ARP , OR DHCP packet, driver must be in active mode. */
 681        if (pattrib->icmp_pkt == 1)
 682                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_LEAVE, 1);
 683        else if (pattrib->dhcp_pkt == 1)
 684                rtw_lps_ctrl_wk_cmd(padapter, LPS_CTRL_SPECIAL_PACKET, 1);
 685
 686        bmcast = IS_MCAST(pattrib->ra);
 687
 688        /*  get sta_info */
 689        if (bmcast) {
 690                psta = rtw_get_bcmc_stainfo(padapter);
 691        } else {
 692                psta = rtw_get_stainfo(pstapriv, pattrib->ra);
 693                if (!psta)      { /*  if we cannot get psta => drop the pkt */
 694                        res = _FAIL;
 695                        goto exit;
 696                } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) && (!(psta->state & _FW_LINKED))) {
 697                        res = _FAIL;
 698                        goto exit;
 699                }
 700        }
 701
 702        if (!psta) {
 703                /*  if we cannot get psta => drop the pkt */
 704                res = _FAIL;
 705                goto exit;
 706        }
 707
 708        if (!(psta->state & _FW_LINKED))
 709                return _FAIL;
 710
 711        /* TODO:_lock */
 712        if (update_attrib_sec_info(padapter, pattrib, psta) == _FAIL) {
 713                res = _FAIL;
 714                goto exit;
 715        }
 716
 717        update_attrib_phy_info(padapter, pattrib, psta);
 718
 719        pattrib->psta = psta;
 720        /* TODO:_unlock */
 721
 722        pattrib->pctrl = 0;
 723
 724        pattrib->ack_policy = 0;
 725        /*  get ether_hdr_len */
 726        pattrib->pkt_hdrlen = ETH_HLEN;/* pattrib->ether_type == 0x8100) ? (14 + 4): 14; vlan tag */
 727
 728        pattrib->hdrlen = WLAN_HDR_A3_LEN;
 729        pattrib->subtype = WIFI_DATA_TYPE;
 730        pattrib->priority = 0;
 731
 732        if (check_fwstate(pmlmepriv, WIFI_AP_STATE|WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE)) {
 733                if (pattrib->qos_en)
 734                        set_qos(&pktfile, pattrib);
 735        } else {
 736                if (pqospriv->qos_option) {
 737                        set_qos(&pktfile, pattrib);
 738
 739                        if (pmlmepriv->acm_mask != 0)
 740                                pattrib->priority = qos_acm(pmlmepriv->acm_mask, pattrib->priority);
 741                }
 742        }
 743
 744        /* pattrib->priority = 5; force to used VI queue, for testing */
 745
 746exit:
 747        return res;
 748}
 749
 750static s32 xmitframe_addmic(struct adapter *padapter, struct xmit_frame *pxmitframe)
 751{
 752        signed int                      curfragnum, length;
 753        u8 *pframe, *payload, mic[8];
 754        struct mic_data micdata;
 755        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 756        struct security_priv *psecuritypriv = &padapter->securitypriv;
 757        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 758        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 759        u8 hw_hdr_offset = 0;
 760        signed int bmcst = IS_MCAST(pattrib->ra);
 761
 762        hw_hdr_offset = TXDESC_OFFSET;
 763
 764        if (pattrib->encrypt == _TKIP_) {
 765                /* encode mic code */
 766                {
 767                        u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
 768
 769                        pframe = pxmitframe->buf_addr + hw_hdr_offset;
 770
 771                        if (bmcst) {
 772                                if (!memcmp(psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey, null_key, 16))
 773                                        return _FAIL;
 774                                /* start to calculate the mic code */
 775                                rtw_secmicsetkey(&micdata, psecuritypriv->dot118021XGrptxmickey[psecuritypriv->dot118021XGrpKeyid].skey);
 776                        } else {
 777                                if (!memcmp(&pattrib->dot11tkiptxmickey.skey[0], null_key, 16))
 778                                        return _FAIL;
 779                                /* start to calculate the mic code */
 780                                rtw_secmicsetkey(&micdata, &pattrib->dot11tkiptxmickey.skey[0]);
 781                        }
 782
 783                        if (pframe[1]&1) {   /* ToDS == 1 */
 784                                rtw_secmicappend(&micdata, &pframe[16], 6);  /* DA */
 785                                if (pframe[1]&2)  /* From Ds == 1 */
 786                                        rtw_secmicappend(&micdata, &pframe[24], 6);
 787                                else
 788                                        rtw_secmicappend(&micdata, &pframe[10], 6);
 789                        } else {        /* ToDS == 0 */
 790                                rtw_secmicappend(&micdata, &pframe[4], 6);   /* DA */
 791                                if (pframe[1]&2)  /* From Ds == 1 */
 792                                        rtw_secmicappend(&micdata, &pframe[16], 6);
 793                                else
 794                                        rtw_secmicappend(&micdata, &pframe[10], 6);
 795                        }
 796
 797                        if (pattrib->qos_en)
 798                                priority[0] = (u8)pxmitframe->attrib.priority;
 799
 800                        rtw_secmicappend(&micdata, &priority[0], 4);
 801
 802                        payload = pframe;
 803
 804                        for (curfragnum = 0; curfragnum < pattrib->nr_frags; curfragnum++) {
 805                                payload = (u8 *)round_up((SIZE_PTR)(payload), 4);
 806                                payload = payload+pattrib->hdrlen+pattrib->iv_len;
 807
 808                                if ((curfragnum+1) == pattrib->nr_frags) {
 809                                        length = pattrib->last_txcmdsz-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
 810                                        rtw_secmicappend(&micdata, payload, length);
 811                                        payload = payload+length;
 812                                } else {
 813                                        length = pxmitpriv->frag_len-pattrib->hdrlen-pattrib->iv_len-((pattrib->bswenc) ? pattrib->icv_len : 0);
 814                                        rtw_secmicappend(&micdata, payload, length);
 815                                        payload = payload+length+pattrib->icv_len;
 816                                }
 817                        }
 818                        rtw_secgetmic(&micdata, &mic[0]);
 819                        /* add mic code  and add the mic code length in last_txcmdsz */
 820
 821                        memcpy(payload, &mic[0], 8);
 822                        pattrib->last_txcmdsz += 8;
 823                        }
 824        }
 825        return _SUCCESS;
 826}
 827
 828static s32 xmitframe_swencrypt(struct adapter *padapter, struct xmit_frame *pxmitframe)
 829{
 830        struct  pkt_attrib       *pattrib = &pxmitframe->attrib;
 831
 832        if (pattrib->bswenc) {
 833                switch (pattrib->encrypt) {
 834                case _WEP40_:
 835                case _WEP104_:
 836                        rtw_wep_encrypt(padapter, (u8 *)pxmitframe);
 837                        break;
 838                case _TKIP_:
 839                        rtw_tkip_encrypt(padapter, (u8 *)pxmitframe);
 840                        break;
 841                case _AES_:
 842                        rtw_aes_encrypt(padapter, (u8 *)pxmitframe);
 843                        break;
 844                default:
 845                                break;
 846                }
 847        }
 848
 849        return _SUCCESS;
 850}
 851
 852s32 rtw_make_wlanhdr(struct adapter *padapter, u8 *hdr, struct pkt_attrib *pattrib)
 853{
 854        u16 *qc;
 855
 856        struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
 857        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 858        struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 859        u8 qos_option = false;
 860        signed int res = _SUCCESS;
 861        __le16 *fctrl = &pwlanhdr->frame_control;
 862
 863        memset(hdr, 0, WLANHDR_OFFSET);
 864
 865        SetFrameSubType(fctrl, pattrib->subtype);
 866
 867        if (pattrib->subtype & WIFI_DATA_TYPE) {
 868                if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE) == true) {
 869                        /* to_ds = 1, fr_ds = 0; */
 870
 871                        {
 872                                /*  1.Data transfer to AP */
 873                                /*  2.Arp pkt will relayed by AP */
 874                                SetToDs(fctrl);
 875                                memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv), ETH_ALEN);
 876                                memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 877                                memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
 878                        }
 879
 880                        if (pqospriv->qos_option)
 881                                qos_option = true;
 882                } else if (check_fwstate(pmlmepriv,  WIFI_AP_STATE) == true) {
 883                        /* to_ds = 0, fr_ds = 1; */
 884                        SetFrDs(fctrl);
 885                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 886                        memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv), ETH_ALEN);
 887                        memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
 888
 889                        if (pattrib->qos_en)
 890                                qos_option = true;
 891                } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
 892                (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
 893                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 894                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 895                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv), ETH_ALEN);
 896
 897                        if (pattrib->qos_en)
 898                                qos_option = true;
 899                } else {
 900                        res = _FAIL;
 901                        goto exit;
 902                }
 903
 904                if (pattrib->mdata)
 905                        SetMData(fctrl);
 906
 907                if (pattrib->encrypt)
 908                        SetPrivacy(fctrl);
 909
 910                if (qos_option) {
 911                        qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
 912
 913                        if (pattrib->priority)
 914                                SetPriority(qc, pattrib->priority);
 915
 916                        SetEOSP(qc, pattrib->eosp);
 917
 918                        SetAckpolicy(qc, pattrib->ack_policy);
 919                }
 920
 921                /* TODO: fill HT Control Field */
 922
 923                /* Update Seq Num will be handled by f/w */
 924                {
 925                        struct sta_info *psta;
 926
 927                        psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
 928                        if (pattrib->psta != psta)
 929                                return _FAIL;
 930
 931                        if (!psta)
 932                                return _FAIL;
 933
 934                        if (!(psta->state & _FW_LINKED))
 935                                return _FAIL;
 936
 937                        if (psta) {
 938                                psta->sta_xmitpriv.txseq_tid[pattrib->priority]++;
 939                                psta->sta_xmitpriv.txseq_tid[pattrib->priority] &= 0xFFF;
 940                                pattrib->seqnum = psta->sta_xmitpriv.txseq_tid[pattrib->priority];
 941
 942                                SetSeqNum(hdr, pattrib->seqnum);
 943
 944                                /* check if enable ampdu */
 945                                if (pattrib->ht_en && psta->htpriv.ampdu_enable)
 946                                        if (psta->htpriv.agg_enable_bitmap & BIT(pattrib->priority))
 947                                                pattrib->ampdu_en = true;
 948
 949                                /* re-check if enable ampdu by BA_starting_seqctrl */
 950                                if (pattrib->ampdu_en == true) {
 951                                        u16 tx_seq;
 952
 953                                        tx_seq = psta->BA_starting_seqctrl[pattrib->priority & 0x0f];
 954
 955                                        /* check BA_starting_seqctrl */
 956                                        if (SN_LESS(pattrib->seqnum, tx_seq)) {
 957                                                pattrib->ampdu_en = false;/* AGG BK */
 958                                        } else if (SN_EQUAL(pattrib->seqnum, tx_seq)) {
 959                                                psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (tx_seq+1)&0xfff;
 960
 961                                                pattrib->ampdu_en = true;/* AGG EN */
 962                                        } else {
 963                                                psta->BA_starting_seqctrl[pattrib->priority & 0x0f] = (pattrib->seqnum+1)&0xfff;
 964                                                pattrib->ampdu_en = true;/* AGG EN */
 965                                        }
 966                                }
 967                        }
 968                }
 969        } else {
 970        }
 971
 972exit:
 973        return res;
 974}
 975
 976s32 rtw_txframes_pending(struct adapter *padapter)
 977{
 978        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 979
 980        return ((!list_empty(&pxmitpriv->be_pending.queue)) ||
 981                         (!list_empty(&pxmitpriv->bk_pending.queue)) ||
 982                         (!list_empty(&pxmitpriv->vi_pending.queue)) ||
 983                         (!list_empty(&pxmitpriv->vo_pending.queue)));
 984}
 985
 986/*
 987 * Calculate wlan 802.11 packet MAX size from pkt_attrib
 988 * This function doesn't consider fragment case
 989 */
 990u32 rtw_calculate_wlan_pkt_size_by_attribue(struct pkt_attrib *pattrib)
 991{
 992        u32 len = 0;
 993
 994        len = pattrib->hdrlen + pattrib->iv_len; /*  WLAN Header and IV */
 995        len += SNAP_SIZE + sizeof(u16); /*  LLC */
 996        len += pattrib->pktlen;
 997        if (pattrib->encrypt == _TKIP_)
 998                len += 8; /*  MIC */
 999        len += ((pattrib->bswenc) ? pattrib->icv_len : 0); /*  ICV */
1000
1001        return len;
1002}
1003
1004/*
1005 * This sub-routine will perform all the following:
1006 * 1. remove 802.3 header.
1007 * 2. create wlan_header, based on the info in pxmitframe
1008 * 3. append sta's iv/ext-iv
1009 * 4. append LLC
1010 * 5. move frag chunk from pframe to pxmitframe->mem
1011 * 6. apply sw-encrypt, if necessary.
1012 */
1013s32 rtw_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe)
1014{
1015        struct pkt_file pktfile;
1016
1017        s32 frg_inx, frg_len, mpdu_len, llc_sz, mem_sz;
1018
1019        SIZE_PTR addr;
1020
1021        u8 *pframe, *mem_start;
1022        u8 hw_hdr_offset;
1023
1024        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1025
1026        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
1027
1028        u8 *pbuf_start;
1029
1030        s32 bmcst = IS_MCAST(pattrib->ra);
1031        s32 res = _SUCCESS;
1032
1033        if (!pxmitframe->buf_addr)
1034                return _FAIL;
1035
1036        pbuf_start = pxmitframe->buf_addr;
1037
1038        hw_hdr_offset = TXDESC_OFFSET;
1039        mem_start = pbuf_start +        hw_hdr_offset;
1040
1041        if (rtw_make_wlanhdr(padapter, mem_start, pattrib) == _FAIL) {
1042                res = _FAIL;
1043                goto exit;
1044        }
1045
1046        _rtw_open_pktfile(pkt, &pktfile);
1047        _rtw_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
1048
1049        frg_inx = 0;
1050        frg_len = pxmitpriv->frag_len - 4;/* 2346-4 = 2342 */
1051
1052        while (1) {
1053                llc_sz = 0;
1054
1055                mpdu_len = frg_len;
1056
1057                pframe = mem_start;
1058
1059                SetMFrag(mem_start);
1060
1061                pframe += pattrib->hdrlen;
1062                mpdu_len -= pattrib->hdrlen;
1063
1064                /* adding icv, if necessary... */
1065                if (pattrib->iv_len) {
1066                        memcpy(pframe, pattrib->iv, pattrib->iv_len);
1067
1068                        pframe += pattrib->iv_len;
1069
1070                        mpdu_len -= pattrib->iv_len;
1071                }
1072
1073                if (frg_inx == 0) {
1074                        llc_sz = rtw_put_snap(pframe, pattrib->ether_type);
1075                        pframe += llc_sz;
1076                        mpdu_len -= llc_sz;
1077                }
1078
1079                if ((pattrib->icv_len > 0) && (pattrib->bswenc))
1080                        mpdu_len -= pattrib->icv_len;
1081
1082                if (bmcst) {
1083                        /*  don't do fragment to broadcast/multicast packets */
1084                        mem_sz = _rtw_pktfile_read(&pktfile, pframe, pattrib->pktlen);
1085                } else {
1086                        mem_sz = _rtw_pktfile_read(&pktfile, pframe, mpdu_len);
1087                }
1088
1089                pframe += mem_sz;
1090
1091                if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1092                        memcpy(pframe, pattrib->icv, pattrib->icv_len);
1093                        pframe += pattrib->icv_len;
1094                }
1095
1096                frg_inx++;
1097
1098                if (bmcst || (rtw_endofpktfile(&pktfile) == true)) {
1099                        pattrib->nr_frags = frg_inx;
1100
1101                        pattrib->last_txcmdsz = pattrib->hdrlen + pattrib->iv_len + ((pattrib->nr_frags == 1) ? llc_sz:0) +
1102                                        ((pattrib->bswenc) ? pattrib->icv_len : 0) + mem_sz;
1103
1104                        ClearMFrag(mem_start);
1105
1106                        break;
1107                }
1108
1109                addr = (SIZE_PTR)(pframe);
1110
1111                mem_start = (unsigned char *)round_up(addr, 4) + hw_hdr_offset;
1112                memcpy(mem_start, pbuf_start + hw_hdr_offset, pattrib->hdrlen);
1113        }
1114
1115        if (xmitframe_addmic(padapter, pxmitframe) == _FAIL) {
1116                res = _FAIL;
1117                goto exit;
1118        }
1119
1120        xmitframe_swencrypt(padapter, pxmitframe);
1121
1122        if (bmcst == false)
1123                update_attrib_vcs_info(padapter, pxmitframe);
1124        else
1125                pattrib->vcs_mode = NONE_VCS;
1126
1127exit:
1128        return res;
1129}
1130
1131/* broadcast or multicast management pkt use BIP, unicast management pkt use CCMP encryption */
1132s32 rtw_mgmt_xmitframe_coalesce(struct adapter *padapter, struct sk_buff *pkt, struct xmit_frame *pxmitframe)
1133{
1134        u8 *pframe, *mem_start = NULL, *tmp_buf = NULL;
1135        u8 subtype;
1136        struct sta_info *psta = NULL;
1137        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1138        s32 bmcst = IS_MCAST(pattrib->ra);
1139        u8 *BIP_AAD = NULL;
1140        u8 *MGMT_body = NULL;
1141
1142        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1143        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1144        struct ieee80211_hdr    *pwlanhdr;
1145        u8 MME[_MME_IE_LENGTH_];
1146        u32 ori_len;
1147
1148        mem_start = pframe = (u8 *)(pxmitframe->buf_addr) + TXDESC_OFFSET;
1149        pwlanhdr = (struct ieee80211_hdr *)pframe;
1150
1151        ori_len = BIP_AAD_SIZE+pattrib->pktlen;
1152        tmp_buf = BIP_AAD = rtw_zmalloc(ori_len);
1153        subtype = GetFrameSubType(pframe); /* bit(7)~bit(2) */
1154
1155        if (!BIP_AAD)
1156                return _FAIL;
1157
1158        spin_lock_bh(&padapter->security_key_mutex);
1159
1160        /* only support station mode */
1161        if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE) || !check_fwstate(pmlmepriv, _FW_LINKED))
1162                goto xmitframe_coalesce_success;
1163
1164        /* IGTK key is not install, it may not support 802.11w */
1165        if (!padapter->securitypriv.binstallBIPkey)
1166                goto xmitframe_coalesce_success;
1167
1168        /* station mode doesn't need TX BIP, just ready the code */
1169        if (bmcst) {
1170                int frame_body_len;
1171                u8 mic[16];
1172
1173                memset(MME, 0, 18);
1174
1175                /* other types doesn't need the BIP */
1176                if (GetFrameSubType(pframe) != WIFI_DEAUTH && GetFrameSubType(pframe) != WIFI_DISASSOC)
1177                        goto xmitframe_coalesce_fail;
1178
1179                MGMT_body = pframe + sizeof(struct ieee80211_hdr_3addr);
1180                pframe += pattrib->pktlen;
1181
1182                /* octent 0 and 1 is key index , BIP keyid is 4 or 5, LSB only need octent 0 */
1183                MME[0] = padapter->securitypriv.dot11wBIPKeyid;
1184                /* copy packet number */
1185                memcpy(&MME[2], &pmlmeext->mgnt_80211w_IPN, 6);
1186                /* increase the packet number */
1187                pmlmeext->mgnt_80211w_IPN++;
1188
1189                /* add MME IE with MIC all zero, MME string doesn't include element id and length */
1190                pframe = rtw_set_ie(pframe, WLAN_EID_MMIE, 16,
1191                                    MME, &pattrib->pktlen);
1192                pattrib->last_txcmdsz = pattrib->pktlen;
1193                /*  total frame length - header length */
1194                frame_body_len = pattrib->pktlen - sizeof(struct ieee80211_hdr_3addr);
1195
1196                /* conscruct AAD, copy frame control field */
1197                memcpy(BIP_AAD, &pwlanhdr->frame_control, 2);
1198                ClearRetry(BIP_AAD);
1199                ClearPwrMgt(BIP_AAD);
1200                ClearMData(BIP_AAD);
1201                /* conscruct AAD, copy address 1 to address 3 */
1202                memcpy(BIP_AAD+2, pwlanhdr->addr1, 18);
1203                /* copy management fram body */
1204                memcpy(BIP_AAD+BIP_AAD_SIZE, MGMT_body, frame_body_len);
1205                /* calculate mic */
1206                if (omac1_aes_128(padapter->securitypriv.dot11wBIPKey[padapter->securitypriv.dot11wBIPKeyid].skey
1207                        , BIP_AAD, BIP_AAD_SIZE+frame_body_len, mic))
1208                        goto xmitframe_coalesce_fail;
1209
1210                /* copy right BIP mic value, total is 128bits, we use the 0~63 bits */
1211                memcpy(pframe-8, mic, 8);
1212        } else { /* unicast mgmt frame TX */
1213                /* start to encrypt mgmt frame */
1214                if (subtype == WIFI_DEAUTH || subtype == WIFI_DISASSOC ||
1215                        subtype == WIFI_REASSOCREQ || subtype == WIFI_ACTION) {
1216                        if (pattrib->psta)
1217                                psta = pattrib->psta;
1218                        else
1219                                psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1220
1221                        if (!psta)
1222                                goto xmitframe_coalesce_fail;
1223
1224                        if (!(psta->state & _FW_LINKED) || !pxmitframe->buf_addr)
1225                                goto xmitframe_coalesce_fail;
1226
1227                        /* according 802.11-2012 standard, these five types are not robust types */
1228                        if (subtype == WIFI_ACTION &&
1229                        (pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_PUBLIC ||
1230                        pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_HT ||
1231                        pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_UNPROTECTED_WNM ||
1232                        pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_SELF_PROTECTED  ||
1233                        pframe[WLAN_HDR_A3_LEN] == RTW_WLAN_CATEGORY_P2P))
1234                                goto xmitframe_coalesce_fail;
1235                        /* before encrypt dump the management packet content */
1236                        if (pattrib->encrypt > 0)
1237                                memcpy(pattrib->dot118021x_UncstKey.skey, psta->dot118021x_UncstKey.skey, 16);
1238                        /* bakeup original management packet */
1239                        memcpy(tmp_buf, pframe, pattrib->pktlen);
1240                        /* move to data portion */
1241                        pframe += pattrib->hdrlen;
1242
1243                        /* 802.11w unicast management packet must be _AES_ */
1244                        pattrib->iv_len = 8;
1245                        /* it's MIC of AES */
1246                        pattrib->icv_len = 8;
1247
1248                        switch (pattrib->encrypt) {
1249                        case _AES_:
1250                                        /* set AES IV header */
1251                                        AES_IV(pattrib->iv, psta->dot11wtxpn, 0);
1252                                break;
1253                        default:
1254                                goto xmitframe_coalesce_fail;
1255                        }
1256                        /* insert iv header into management frame */
1257                        memcpy(pframe, pattrib->iv, pattrib->iv_len);
1258                        pframe += pattrib->iv_len;
1259                        /* copy mgmt data portion after CCMP header */
1260                        memcpy(pframe, tmp_buf+pattrib->hdrlen, pattrib->pktlen-pattrib->hdrlen);
1261                        /* move pframe to end of mgmt pkt */
1262                        pframe += pattrib->pktlen-pattrib->hdrlen;
1263                        /* add 8 bytes CCMP IV header to length */
1264                        pattrib->pktlen += pattrib->iv_len;
1265                        if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
1266                                memcpy(pframe, pattrib->icv, pattrib->icv_len);
1267                                pframe += pattrib->icv_len;
1268                        }
1269                        /* add 8 bytes MIC */
1270                        pattrib->pktlen += pattrib->icv_len;
1271                        /* set final tx command size */
1272                        pattrib->last_txcmdsz = pattrib->pktlen;
1273
1274                        /* set protected bit must be beofre SW encrypt */
1275                        SetPrivacy(mem_start);
1276                        /* software encrypt */
1277                        xmitframe_swencrypt(padapter, pxmitframe);
1278                }
1279        }
1280
1281xmitframe_coalesce_success:
1282        spin_unlock_bh(&padapter->security_key_mutex);
1283        kfree(BIP_AAD);
1284        return _SUCCESS;
1285
1286xmitframe_coalesce_fail:
1287        spin_unlock_bh(&padapter->security_key_mutex);
1288        kfree(BIP_AAD);
1289        return _FAIL;
1290}
1291
1292/* Logical Link Control(LLC) SubNetwork Attachment Point(SNAP) header
1293 * IEEE LLC/SNAP header contains 8 octets
1294 * First 3 octets comprise the LLC portion
1295 * SNAP portion, 5 octets, is divided into two fields:
1296 *Organizationally Unique Identifier(OUI), 3 octets,
1297 *type, defined by that organization, 2 octets.
1298 */
1299s32 rtw_put_snap(u8 *data, u16 h_proto)
1300{
1301        struct ieee80211_snap_hdr *snap;
1302        u8 *oui;
1303
1304        snap = (struct ieee80211_snap_hdr *)data;
1305        snap->dsap = 0xaa;
1306        snap->ssap = 0xaa;
1307        snap->ctrl = 0x03;
1308
1309        if (h_proto == 0x8137 || h_proto == 0x80f3)
1310                oui = P802_1H_OUI;
1311        else
1312                oui = RFC1042_OUI;
1313
1314        snap->oui[0] = oui[0];
1315        snap->oui[1] = oui[1];
1316        snap->oui[2] = oui[2];
1317
1318        *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
1319
1320        return SNAP_SIZE + sizeof(u16);
1321}
1322
1323void rtw_update_protection(struct adapter *padapter, u8 *ie, uint ie_len)
1324{
1325        uint    protection;
1326        u8 *perp;
1327        signed int       erp_len;
1328        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
1329        struct  registry_priv *pregistrypriv = &padapter->registrypriv;
1330
1331        switch (pxmitpriv->vcs_setting) {
1332        case DISABLE_VCS:
1333                pxmitpriv->vcs = NONE_VCS;
1334                break;
1335
1336        case ENABLE_VCS:
1337                break;
1338
1339        case AUTO_VCS:
1340        default:
1341                perp = rtw_get_ie(ie, WLAN_EID_ERP_INFO, &erp_len, ie_len);
1342                if (!perp) {
1343                        pxmitpriv->vcs = NONE_VCS;
1344                } else {
1345                        protection = (*(perp + 2)) & BIT(1);
1346                        if (protection) {
1347                                if (pregistrypriv->vcs_type == RTS_CTS)
1348                                        pxmitpriv->vcs = RTS_CTS;
1349                                else
1350                                        pxmitpriv->vcs = CTS_TO_SELF;
1351                        } else {
1352                                pxmitpriv->vcs = NONE_VCS;
1353                        }
1354                }
1355
1356                break;
1357        }
1358}
1359
1360void rtw_count_tx_stats(struct adapter *padapter, struct xmit_frame *pxmitframe, int sz)
1361{
1362        struct sta_info *psta = NULL;
1363        struct stainfo_stats *pstats = NULL;
1364        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1365        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1366        u8 pkt_num = 1;
1367
1368        if ((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG) {
1369                pkt_num = pxmitframe->agg_num;
1370
1371                pmlmepriv->LinkDetectInfo.NumTxOkInPeriod += pkt_num;
1372
1373                pxmitpriv->tx_pkts += pkt_num;
1374
1375                pxmitpriv->tx_bytes += sz;
1376
1377                psta = pxmitframe->attrib.psta;
1378                if (psta) {
1379                        pstats = &psta->sta_stats;
1380
1381                        pstats->tx_pkts += pkt_num;
1382
1383                        pstats->tx_bytes += sz;
1384                }
1385        }
1386}
1387
1388static struct xmit_buf *__rtw_alloc_cmd_xmitbuf(struct xmit_priv *pxmitpriv,
1389                enum cmdbuf_type buf_type)
1390{
1391        struct xmit_buf *pxmitbuf =  NULL;
1392
1393        pxmitbuf = &pxmitpriv->pcmd_xmitbuf[buf_type];
1394        if (pxmitbuf) {
1395                pxmitbuf->priv_data = NULL;
1396
1397                pxmitbuf->len = 0;
1398                pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
1399                pxmitbuf->agg_num = 0;
1400                pxmitbuf->pg_num = 0;
1401
1402                if (pxmitbuf->sctx)
1403                        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1404        }
1405
1406        return pxmitbuf;
1407}
1408
1409struct xmit_frame *__rtw_alloc_cmdxmitframe(struct xmit_priv *pxmitpriv,
1410                enum cmdbuf_type buf_type)
1411{
1412        struct xmit_frame               *pcmdframe;
1413        struct xmit_buf         *pxmitbuf;
1414
1415        pcmdframe = rtw_alloc_xmitframe(pxmitpriv);
1416        if (!pcmdframe)
1417                return NULL;
1418
1419        pxmitbuf = __rtw_alloc_cmd_xmitbuf(pxmitpriv, buf_type);
1420        if (!pxmitbuf) {
1421                rtw_free_xmitframe(pxmitpriv, pcmdframe);
1422                return NULL;
1423        }
1424
1425        pcmdframe->frame_tag = MGNT_FRAMETAG;
1426
1427        pcmdframe->pxmitbuf = pxmitbuf;
1428
1429        pcmdframe->buf_addr = pxmitbuf->pbuf;
1430
1431        pxmitbuf->priv_data = pcmdframe;
1432
1433        return pcmdframe;
1434}
1435
1436struct xmit_buf *rtw_alloc_xmitbuf_ext(struct xmit_priv *pxmitpriv)
1437{
1438        unsigned long irqL;
1439        struct xmit_buf *pxmitbuf =  NULL;
1440        struct list_head *plist, *phead;
1441        struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1442
1443        spin_lock_irqsave(&pfree_queue->lock, irqL);
1444
1445        if (list_empty(&pfree_queue->queue)) {
1446                pxmitbuf = NULL;
1447        } else {
1448                phead = get_list_head(pfree_queue);
1449
1450                plist = get_next(phead);
1451
1452                pxmitbuf = container_of(plist, struct xmit_buf, list);
1453
1454                list_del_init(&pxmitbuf->list);
1455        }
1456
1457        if (pxmitbuf) {
1458                pxmitpriv->free_xmit_extbuf_cnt--;
1459
1460                pxmitbuf->priv_data = NULL;
1461
1462                pxmitbuf->len = 0;
1463                pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
1464                pxmitbuf->agg_num = 1;
1465
1466                if (pxmitbuf->sctx)
1467                        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1468        }
1469
1470        spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1471
1472        return pxmitbuf;
1473}
1474
1475s32 rtw_free_xmitbuf_ext(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1476{
1477        unsigned long irqL;
1478        struct __queue *pfree_queue = &pxmitpriv->free_xmit_extbuf_queue;
1479
1480        if (!pxmitbuf)
1481                return _FAIL;
1482
1483        spin_lock_irqsave(&pfree_queue->lock, irqL);
1484
1485        list_del_init(&pxmitbuf->list);
1486
1487        list_add_tail(&pxmitbuf->list, get_list_head(pfree_queue));
1488        pxmitpriv->free_xmit_extbuf_cnt++;
1489
1490        spin_unlock_irqrestore(&pfree_queue->lock, irqL);
1491
1492        return _SUCCESS;
1493}
1494
1495struct xmit_buf *rtw_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
1496{
1497        unsigned long irqL;
1498        struct xmit_buf *pxmitbuf =  NULL;
1499        struct list_head *plist, *phead;
1500        struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1501
1502        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1503
1504        if (list_empty(&pfree_xmitbuf_queue->queue)) {
1505                pxmitbuf = NULL;
1506        } else {
1507                phead = get_list_head(pfree_xmitbuf_queue);
1508
1509                plist = get_next(phead);
1510
1511                pxmitbuf = container_of(plist, struct xmit_buf, list);
1512
1513                list_del_init(&pxmitbuf->list);
1514        }
1515
1516        if (pxmitbuf) {
1517                pxmitpriv->free_xmitbuf_cnt--;
1518
1519                pxmitbuf->priv_data = NULL;
1520
1521                pxmitbuf->len = 0;
1522                pxmitbuf->pdata = pxmitbuf->ptail = pxmitbuf->phead;
1523                pxmitbuf->agg_num = 0;
1524                pxmitbuf->pg_num = 0;
1525
1526                if (pxmitbuf->sctx)
1527                        rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_ALLOC);
1528        }
1529
1530        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
1531
1532        return pxmitbuf;
1533}
1534
1535s32 rtw_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
1536{
1537        unsigned long irqL;
1538        struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
1539
1540        if (!pxmitbuf)
1541                return _FAIL;
1542
1543        if (pxmitbuf->sctx)
1544                rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_BUF_FREE);
1545
1546        if (pxmitbuf->buf_tag == XMITBUF_CMD) {
1547        } else if (pxmitbuf->buf_tag == XMITBUF_MGNT) {
1548                rtw_free_xmitbuf_ext(pxmitpriv, pxmitbuf);
1549        } else {
1550                spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
1551
1552                list_del_init(&pxmitbuf->list);
1553
1554                list_add_tail(&pxmitbuf->list,
1555                              get_list_head(pfree_xmitbuf_queue));
1556
1557                pxmitpriv->free_xmitbuf_cnt++;
1558                spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
1559        }
1560        return _SUCCESS;
1561}
1562
1563static void rtw_init_xmitframe(struct xmit_frame *pxframe)
1564{
1565        if (pxframe) { /* default value setting */
1566                pxframe->buf_addr = NULL;
1567                pxframe->pxmitbuf = NULL;
1568
1569                memset(&pxframe->attrib, 0, sizeof(struct pkt_attrib));
1570
1571                pxframe->frame_tag = DATA_FRAMETAG;
1572
1573                pxframe->pg_num = 1;
1574                pxframe->agg_num = 1;
1575                pxframe->ack_report = 0;
1576        }
1577}
1578
1579/*
1580 * Calling context:
1581 * 1. OS_TXENTRY
1582 * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
1583 *
1584 * If we turn on USE_RXTHREAD, then, no need for critical section.
1585 * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
1586 *
1587 * Must be very, very cautious...
1588 */
1589struct xmit_frame *rtw_alloc_xmitframe(struct xmit_priv *pxmitpriv)/* _queue *pfree_xmit_queue) */
1590{
1591        /*
1592         *      Please remember to use all the osdep_service api,
1593         *      and lock/unlock or _enter/_exit critical to protect
1594         *      pfree_xmit_queue
1595         */
1596
1597        struct xmit_frame *pxframe = NULL;
1598        struct list_head *plist, *phead;
1599        struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
1600
1601        spin_lock_bh(&pfree_xmit_queue->lock);
1602
1603        if (list_empty(&pfree_xmit_queue->queue)) {
1604                pxframe =  NULL;
1605        } else {
1606                phead = get_list_head(pfree_xmit_queue);
1607
1608                plist = get_next(phead);
1609
1610                pxframe = container_of(plist, struct xmit_frame, list);
1611
1612                list_del_init(&pxframe->list);
1613                pxmitpriv->free_xmitframe_cnt--;
1614        }
1615
1616        spin_unlock_bh(&pfree_xmit_queue->lock);
1617
1618        rtw_init_xmitframe(pxframe);
1619        return pxframe;
1620}
1621
1622struct xmit_frame *rtw_alloc_xmitframe_ext(struct xmit_priv *pxmitpriv)
1623{
1624        struct xmit_frame *pxframe = NULL;
1625        struct list_head *plist, *phead;
1626        struct __queue *queue = &pxmitpriv->free_xframe_ext_queue;
1627
1628        spin_lock_bh(&queue->lock);
1629
1630        if (list_empty(&queue->queue)) {
1631                pxframe =  NULL;
1632        } else {
1633                phead = get_list_head(queue);
1634                plist = get_next(phead);
1635                pxframe = container_of(plist, struct xmit_frame, list);
1636
1637                list_del_init(&pxframe->list);
1638                pxmitpriv->free_xframe_ext_cnt--;
1639        }
1640
1641        spin_unlock_bh(&queue->lock);
1642
1643        rtw_init_xmitframe(pxframe);
1644
1645        return pxframe;
1646}
1647
1648struct xmit_frame *rtw_alloc_xmitframe_once(struct xmit_priv *pxmitpriv)
1649{
1650        struct xmit_frame *pxframe = NULL;
1651        u8 *alloc_addr;
1652
1653        alloc_addr = rtw_zmalloc(sizeof(struct xmit_frame) + 4);
1654
1655        if (!alloc_addr)
1656                goto exit;
1657
1658        pxframe = (struct xmit_frame *)N_BYTE_ALIGMENT((SIZE_PTR)(alloc_addr), 4);
1659        pxframe->alloc_addr = alloc_addr;
1660
1661        pxframe->padapter = pxmitpriv->adapter;
1662        pxframe->frame_tag = NULL_FRAMETAG;
1663
1664        pxframe->pkt = NULL;
1665
1666        pxframe->buf_addr = NULL;
1667        pxframe->pxmitbuf = NULL;
1668
1669        rtw_init_xmitframe(pxframe);
1670
1671exit:
1672        return pxframe;
1673}
1674
1675s32 rtw_free_xmitframe(struct xmit_priv *pxmitpriv, struct xmit_frame *pxmitframe)
1676{
1677        struct __queue *queue = NULL;
1678        struct adapter *padapter = pxmitpriv->adapter;
1679        struct sk_buff *pndis_pkt = NULL;
1680
1681        if (!pxmitframe)
1682                goto exit;
1683
1684        if (pxmitframe->pkt) {
1685                pndis_pkt = pxmitframe->pkt;
1686                pxmitframe->pkt = NULL;
1687        }
1688
1689        if (pxmitframe->alloc_addr) {
1690                kfree(pxmitframe->alloc_addr);
1691                goto check_pkt_complete;
1692        }
1693
1694        if (pxmitframe->ext_tag == 0)
1695                queue = &pxmitpriv->free_xmit_queue;
1696        else if (pxmitframe->ext_tag == 1)
1697                queue = &pxmitpriv->free_xframe_ext_queue;
1698        else {
1699        }
1700
1701        spin_lock_bh(&queue->lock);
1702
1703        list_del_init(&pxmitframe->list);
1704        list_add_tail(&pxmitframe->list, get_list_head(queue));
1705        if (pxmitframe->ext_tag == 0)
1706                pxmitpriv->free_xmitframe_cnt++;
1707        else if (pxmitframe->ext_tag == 1)
1708                pxmitpriv->free_xframe_ext_cnt++;
1709
1710        spin_unlock_bh(&queue->lock);
1711
1712check_pkt_complete:
1713
1714        if (pndis_pkt)
1715                rtw_os_pkt_complete(padapter, pndis_pkt);
1716
1717exit:
1718        return _SUCCESS;
1719}
1720
1721void rtw_free_xmitframe_queue(struct xmit_priv *pxmitpriv, struct __queue *pframequeue)
1722{
1723        struct list_head *plist, *phead, *tmp;
1724        struct  xmit_frame      *pxmitframe;
1725
1726        spin_lock_bh(&pframequeue->lock);
1727
1728        phead = get_list_head(pframequeue);
1729        list_for_each_safe(plist, tmp, phead) {
1730                pxmitframe = list_entry(plist, struct xmit_frame, list);
1731
1732                rtw_free_xmitframe(pxmitpriv, pxmitframe);
1733        }
1734        spin_unlock_bh(&pframequeue->lock);
1735}
1736
1737s32 rtw_xmitframe_enqueue(struct adapter *padapter, struct xmit_frame *pxmitframe)
1738{
1739        if (rtw_xmit_classifier(padapter, pxmitframe) == _FAIL)
1740                return _FAIL;
1741
1742        return _SUCCESS;
1743}
1744
1745struct tx_servq *rtw_get_sta_pending(struct adapter *padapter, struct sta_info *psta, signed int up, u8 *ac)
1746{
1747        struct tx_servq *ptxservq = NULL;
1748
1749        switch (up) {
1750        case 1:
1751        case 2:
1752                ptxservq = &psta->sta_xmitpriv.bk_q;
1753                *(ac) = 3;
1754                break;
1755
1756        case 4:
1757        case 5:
1758                ptxservq = &psta->sta_xmitpriv.vi_q;
1759                *(ac) = 1;
1760                break;
1761
1762        case 6:
1763        case 7:
1764                ptxservq = &psta->sta_xmitpriv.vo_q;
1765                *(ac) = 0;
1766                break;
1767
1768        case 0:
1769        case 3:
1770        default:
1771                ptxservq = &psta->sta_xmitpriv.be_q;
1772                *(ac) = 2;
1773        break;
1774        }
1775
1776        return ptxservq;
1777}
1778
1779/*
1780 * Will enqueue pxmitframe to the proper queue,
1781 * and indicate it to xx_pending list.....
1782 */
1783s32 rtw_xmit_classifier(struct adapter *padapter, struct xmit_frame *pxmitframe)
1784{
1785        u8 ac_index;
1786        struct sta_info *psta;
1787        struct tx_servq *ptxservq;
1788        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
1789        struct hw_xmit  *phwxmits =  padapter->xmitpriv.hwxmits;
1790        signed int res = _SUCCESS;
1791
1792        psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
1793        if (pattrib->psta != psta)
1794                return _FAIL;
1795
1796        if (!psta) {
1797                res = _FAIL;
1798                goto exit;
1799        }
1800
1801        if (!(psta->state & _FW_LINKED))
1802                return _FAIL;
1803
1804        ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
1805
1806        if (list_empty(&ptxservq->tx_pending))
1807                list_add_tail(&ptxservq->tx_pending, get_list_head(phwxmits[ac_index].sta_queue));
1808
1809        list_add_tail(&pxmitframe->list, get_list_head(&ptxservq->sta_pending));
1810        ptxservq->qcnt++;
1811        phwxmits[ac_index].accnt++;
1812
1813exit:
1814
1815        return res;
1816}
1817
1818s32 rtw_alloc_hwxmits(struct adapter *padapter)
1819{
1820        struct hw_xmit *hwxmits;
1821        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1822
1823        pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
1824
1825        pxmitpriv->hwxmits = NULL;
1826
1827        pxmitpriv->hwxmits = rtw_zmalloc(sizeof(struct hw_xmit) * pxmitpriv->hwxmit_entry);
1828
1829        if (!pxmitpriv->hwxmits)
1830                return _FAIL;
1831
1832        hwxmits = pxmitpriv->hwxmits;
1833
1834        if (pxmitpriv->hwxmit_entry == 5) {
1835                hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
1836
1837                hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
1838
1839                hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
1840
1841                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
1842
1843                hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
1844        } else if (pxmitpriv->hwxmit_entry == 4) {
1845                hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
1846
1847                hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
1848
1849                hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
1850
1851                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
1852        } else {
1853        }
1854
1855        return _SUCCESS;
1856}
1857
1858void rtw_free_hwxmits(struct adapter *padapter)
1859{
1860        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1861
1862        kfree(pxmitpriv->hwxmits);
1863}
1864
1865void rtw_init_hwxmits(struct hw_xmit *phwxmit, signed int entry)
1866{
1867        signed int i;
1868
1869        for (i = 0; i < entry; i++, phwxmit++)
1870                phwxmit->accnt = 0;
1871}
1872
1873u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
1874{
1875        u32 addr;
1876        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1877
1878        switch (pattrib->qsel) {
1879        case 0:
1880        case 3:
1881                addr = BE_QUEUE_INX;
1882                break;
1883        case 1:
1884        case 2:
1885                addr = BK_QUEUE_INX;
1886                break;
1887        case 4:
1888        case 5:
1889                addr = VI_QUEUE_INX;
1890                break;
1891        case 6:
1892        case 7:
1893                addr = VO_QUEUE_INX;
1894                break;
1895        case 0x10:
1896                addr = BCN_QUEUE_INX;
1897                break;
1898        case 0x11:/* BC/MC in PS (HIQ) */
1899                addr = HIGH_QUEUE_INX;
1900                break;
1901        case 0x12:
1902        default:
1903                addr = MGT_QUEUE_INX;
1904                break;
1905        }
1906
1907        return addr;
1908}
1909
1910static void do_queue_select(struct adapter      *padapter, struct pkt_attrib *pattrib)
1911{
1912        u8 qsel;
1913
1914        qsel = pattrib->priority;
1915
1916        pattrib->qsel = qsel;
1917}
1918
1919/*
1920 * The main transmit(tx) entry
1921 *
1922 * Return
1923 *1     enqueue
1924 *0     success, hardware will handle this xmit frame(packet)
1925 *<0    fail
1926 */
1927s32 rtw_xmit(struct adapter *padapter, struct sk_buff **ppkt)
1928{
1929        static unsigned long start;
1930        static u32 drop_cnt;
1931
1932        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1933        struct xmit_frame *pxmitframe = NULL;
1934
1935        s32 res;
1936
1937        if (start == 0)
1938                start = jiffies;
1939
1940        pxmitframe = rtw_alloc_xmitframe(pxmitpriv);
1941
1942        if (jiffies_to_msecs(jiffies - start) > 2000) {
1943                start = jiffies;
1944                drop_cnt = 0;
1945        }
1946
1947        if (!pxmitframe) {
1948                drop_cnt++;
1949                return -1;
1950        }
1951
1952        res = update_attrib(padapter, *ppkt, &pxmitframe->attrib);
1953
1954        if (res == _FAIL) {
1955                rtw_free_xmitframe(pxmitpriv, pxmitframe);
1956                return -1;
1957        }
1958        pxmitframe->pkt = *ppkt;
1959
1960        do_queue_select(padapter, &pxmitframe->attrib);
1961
1962        spin_lock_bh(&pxmitpriv->lock);
1963        if (xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == true) {
1964                spin_unlock_bh(&pxmitpriv->lock);
1965                return 1;
1966        }
1967        spin_unlock_bh(&pxmitpriv->lock);
1968
1969        /* pre_xmitframe */
1970        if (rtw_hal_xmit(padapter, pxmitframe) == false)
1971                return 1;
1972
1973        return 0;
1974}
1975
1976#define RTW_HIQ_FILTER_ALLOW_ALL 0
1977#define RTW_HIQ_FILTER_ALLOW_SPECIAL 1
1978#define RTW_HIQ_FILTER_DENY_ALL 2
1979
1980inline bool xmitframe_hiq_filter(struct xmit_frame *xmitframe)
1981{
1982        bool allow = false;
1983        struct adapter *adapter = xmitframe->padapter;
1984        struct registry_priv *registry = &adapter->registrypriv;
1985
1986        if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_SPECIAL) {
1987                struct pkt_attrib *attrib = &xmitframe->attrib;
1988
1989                if (attrib->ether_type == 0x0806 ||
1990                    attrib->ether_type == 0x888e ||
1991                    attrib->dhcp_pkt
1992                )
1993                        allow = true;
1994
1995        } else if (registry->hiq_filter == RTW_HIQ_FILTER_ALLOW_ALL)
1996                allow = true;
1997        else if (registry->hiq_filter == RTW_HIQ_FILTER_DENY_ALL) {
1998        } else
1999                rtw_warn_on(1);
2000
2001        return allow;
2002}
2003
2004signed int xmitframe_enqueue_for_sleeping_sta(struct adapter *padapter, struct xmit_frame *pxmitframe)
2005{
2006        signed int ret = false;
2007        struct sta_info *psta = NULL;
2008        struct sta_priv *pstapriv = &padapter->stapriv;
2009        struct pkt_attrib *pattrib = &pxmitframe->attrib;
2010        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
2011        signed int bmcst = IS_MCAST(pattrib->ra);
2012        bool update_tim = false;
2013
2014        if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == false)
2015                return ret;
2016        psta = rtw_get_stainfo(&padapter->stapriv, pattrib->ra);
2017        if (pattrib->psta != psta)
2018                return false;
2019
2020        if (!psta)
2021                return false;
2022
2023        if (!(psta->state & _FW_LINKED))
2024                return false;
2025
2026        if (pattrib->triggered == 1) {
2027                if (bmcst && xmitframe_hiq_filter(pxmitframe))
2028                        pattrib->qsel = 0x11;/* HIQ */
2029
2030                return ret;
2031        }
2032
2033        if (bmcst) {
2034                spin_lock_bh(&psta->sleep_q.lock);
2035
2036                if (pstapriv->sta_dz_bitmap) { /* if anyone sta is in ps mode */
2037                        /* pattrib->qsel = 0x11;HIQ */
2038
2039                        list_del_init(&pxmitframe->list);
2040
2041                        list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
2042
2043                        psta->sleepq_len++;
2044
2045                        if (!(pstapriv->tim_bitmap & BIT(0)))
2046                                update_tim = true;
2047
2048                        pstapriv->tim_bitmap |= BIT(0);
2049                        pstapriv->sta_dz_bitmap |= BIT(0);
2050
2051                        if (update_tim)
2052                                update_beacon(padapter, WLAN_EID_TIM, NULL, true);
2053                        else
2054                                chk_bmc_sleepq_cmd(padapter);
2055
2056                        ret = true;
2057                }
2058
2059                spin_unlock_bh(&psta->sleep_q.lock);
2060
2061                return ret;
2062        }
2063
2064        spin_lock_bh(&psta->sleep_q.lock);
2065
2066        if (psta->state&WIFI_SLEEP_STATE) {
2067                u8 wmmps_ac = 0;
2068
2069                if (pstapriv->sta_dz_bitmap & BIT(psta->aid)) {
2070                        list_del_init(&pxmitframe->list);
2071
2072                        list_add_tail(&pxmitframe->list, get_list_head(&psta->sleep_q));
2073
2074                        psta->sleepq_len++;
2075
2076                        switch (pattrib->priority) {
2077                        case 1:
2078                        case 2:
2079                                wmmps_ac = psta->uapsd_bk&BIT(0);
2080                                break;
2081                        case 4:
2082                        case 5:
2083                                wmmps_ac = psta->uapsd_vi&BIT(0);
2084                                break;
2085                        case 6:
2086                        case 7:
2087                                wmmps_ac = psta->uapsd_vo&BIT(0);
2088                                break;
2089                        case 0:
2090                        case 3:
2091                        default:
2092                                wmmps_ac = psta->uapsd_be&BIT(0);
2093                                break;
2094                        }
2095
2096                        if (wmmps_ac)
2097                                psta->sleepq_ac_len++;
2098
2099                        if (((psta->has_legacy_ac) && (!wmmps_ac)) || ((!psta->has_legacy_ac) && (wmmps_ac))) {
2100                                if (!(pstapriv->tim_bitmap & BIT(psta->aid)))
2101                                        update_tim = true;
2102
2103                                pstapriv->tim_bitmap |= BIT(psta->aid);
2104
2105                                if (update_tim)
2106                                        /* update BCN for TIM IE */
2107                                        update_beacon(padapter, WLAN_EID_TIM, NULL, true);
2108                        }
2109
2110                        ret = true;
2111                }
2112        }
2113
2114        spin_unlock_bh(&psta->sleep_q.lock);
2115
2116        return ret;
2117}
2118
2119static void dequeue_xmitframes_to_sleeping_queue(struct adapter *padapter, struct sta_info *psta, struct __queue *pframequeue)
2120{
2121        signed int ret;
2122        struct list_head *plist, *phead, *tmp;
2123        u8 ac_index;
2124        struct tx_servq *ptxservq;
2125        struct pkt_attrib       *pattrib;
2126        struct xmit_frame       *pxmitframe;
2127        struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
2128
2129        phead = get_list_head(pframequeue);
2130        list_for_each_safe(plist, tmp, phead) {
2131                pxmitframe = list_entry(plist, struct xmit_frame, list);
2132
2133                pattrib = &pxmitframe->attrib;
2134
2135                pattrib->triggered = 0;
2136
2137                ret = xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe);
2138
2139                if (true == ret) {
2140                        ptxservq = rtw_get_sta_pending(padapter, psta, pattrib->priority, (u8 *)(&ac_index));
2141
2142                        ptxservq->qcnt--;
2143                        phwxmits[ac_index].accnt--;
2144                } else {
2145                }
2146        }
2147}
2148
2149void stop_sta_xmit(struct adapter *padapter, struct sta_info *psta)
2150{
2151        struct sta_info *psta_bmc;
2152        struct sta_xmit_priv *pstaxmitpriv;
2153        struct sta_priv *pstapriv = &padapter->stapriv;
2154        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2155
2156        pstaxmitpriv = &psta->sta_xmitpriv;
2157
2158        /* for BC/MC Frames */
2159        psta_bmc = rtw_get_bcmc_stainfo(padapter);
2160
2161        spin_lock_bh(&pxmitpriv->lock);
2162
2163        psta->state |= WIFI_SLEEP_STATE;
2164
2165        pstapriv->sta_dz_bitmap |= BIT(psta->aid);
2166
2167        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vo_q.sta_pending);
2168        list_del_init(&pstaxmitpriv->vo_q.tx_pending);
2169
2170        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->vi_q.sta_pending);
2171        list_del_init(&pstaxmitpriv->vi_q.tx_pending);
2172
2173        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->be_q.sta_pending);
2174        list_del_init(&pstaxmitpriv->be_q.tx_pending);
2175
2176        dequeue_xmitframes_to_sleeping_queue(padapter, psta, &pstaxmitpriv->bk_q.sta_pending);
2177        list_del_init(&pstaxmitpriv->bk_q.tx_pending);
2178
2179        /* for BC/MC Frames */
2180        pstaxmitpriv = &psta_bmc->sta_xmitpriv;
2181        dequeue_xmitframes_to_sleeping_queue(padapter, psta_bmc, &pstaxmitpriv->be_q.sta_pending);
2182        list_del_init(&pstaxmitpriv->be_q.tx_pending);
2183
2184        spin_unlock_bh(&pxmitpriv->lock);
2185}
2186
2187void wakeup_sta_to_xmit(struct adapter *padapter, struct sta_info *psta)
2188{
2189        u8 update_mask = 0, wmmps_ac = 0;
2190        struct sta_info *psta_bmc;
2191        struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
2192        struct xmit_frame *pxmitframe = NULL;
2193        struct sta_priv *pstapriv = &padapter->stapriv;
2194        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2195
2196        psta_bmc = rtw_get_bcmc_stainfo(padapter);
2197
2198        spin_lock_bh(&pxmitpriv->lock);
2199
2200        xmitframe_phead = get_list_head(&psta->sleep_q);
2201        list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
2202                pxmitframe = list_entry(xmitframe_plist, struct xmit_frame,
2203                                        list);
2204
2205                list_del_init(&pxmitframe->list);
2206
2207                switch (pxmitframe->attrib.priority) {
2208                case 1:
2209                case 2:
2210                        wmmps_ac = psta->uapsd_bk&BIT(1);
2211                        break;
2212                case 4:
2213                case 5:
2214                        wmmps_ac = psta->uapsd_vi&BIT(1);
2215                        break;
2216                case 6:
2217                case 7:
2218                        wmmps_ac = psta->uapsd_vo&BIT(1);
2219                        break;
2220                case 0:
2221                case 3:
2222                default:
2223                        wmmps_ac = psta->uapsd_be&BIT(1);
2224                        break;
2225                }
2226
2227                psta->sleepq_len--;
2228                if (psta->sleepq_len > 0)
2229                        pxmitframe->attrib.mdata = 1;
2230                else
2231                        pxmitframe->attrib.mdata = 0;
2232
2233                if (wmmps_ac) {
2234                        psta->sleepq_ac_len--;
2235                        if (psta->sleepq_ac_len > 0) {
2236                                pxmitframe->attrib.mdata = 1;
2237                                pxmitframe->attrib.eosp = 0;
2238                        } else {
2239                                pxmitframe->attrib.mdata = 0;
2240                                pxmitframe->attrib.eosp = 1;
2241                        }
2242                }
2243
2244                pxmitframe->attrib.triggered = 1;
2245
2246                rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2247        }
2248
2249        if (psta->sleepq_len == 0) {
2250                if (pstapriv->tim_bitmap & BIT(psta->aid))
2251                        update_mask = BIT(0);
2252
2253                pstapriv->tim_bitmap &= ~BIT(psta->aid);
2254
2255                if (psta->state&WIFI_SLEEP_STATE)
2256                        psta->state ^= WIFI_SLEEP_STATE;
2257
2258                if (psta->state & WIFI_STA_ALIVE_CHK_STATE) {
2259                        psta->expire_to = pstapriv->expire_to;
2260                        psta->state ^= WIFI_STA_ALIVE_CHK_STATE;
2261                }
2262
2263                pstapriv->sta_dz_bitmap &= ~BIT(psta->aid);
2264        }
2265
2266        /* for BC/MC Frames */
2267        if (!psta_bmc)
2268                goto _exit;
2269
2270        if ((pstapriv->sta_dz_bitmap&0xfffe) == 0x0) { /* no any sta in ps mode */
2271                xmitframe_phead = get_list_head(&psta_bmc->sleep_q);
2272                list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
2273                        pxmitframe = list_entry(xmitframe_plist,
2274                                                struct xmit_frame, list);
2275
2276                        list_del_init(&pxmitframe->list);
2277
2278                        psta_bmc->sleepq_len--;
2279                        if (psta_bmc->sleepq_len > 0)
2280                                pxmitframe->attrib.mdata = 1;
2281                        else
2282                                pxmitframe->attrib.mdata = 0;
2283
2284                        pxmitframe->attrib.triggered = 1;
2285                        rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2286                }
2287
2288                if (psta_bmc->sleepq_len == 0) {
2289                        if (pstapriv->tim_bitmap & BIT(0))
2290                                update_mask |= BIT(1);
2291
2292                        pstapriv->tim_bitmap &= ~BIT(0);
2293                        pstapriv->sta_dz_bitmap &= ~BIT(0);
2294                }
2295        }
2296
2297_exit:
2298
2299        spin_unlock_bh(&pxmitpriv->lock);
2300
2301        if (update_mask)
2302                update_beacon(padapter, WLAN_EID_TIM, NULL, true);
2303}
2304
2305void xmit_delivery_enabled_frames(struct adapter *padapter, struct sta_info *psta)
2306{
2307        u8 wmmps_ac = 0;
2308        struct list_head *xmitframe_plist, *xmitframe_phead, *tmp;
2309        struct xmit_frame *pxmitframe = NULL;
2310        struct sta_priv *pstapriv = &padapter->stapriv;
2311        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
2312
2313        spin_lock_bh(&pxmitpriv->lock);
2314
2315        xmitframe_phead = get_list_head(&psta->sleep_q);
2316        list_for_each_safe(xmitframe_plist, tmp, xmitframe_phead) {
2317                pxmitframe = list_entry(xmitframe_plist, struct xmit_frame,
2318                                        list);
2319
2320                switch (pxmitframe->attrib.priority) {
2321                case 1:
2322                case 2:
2323                        wmmps_ac = psta->uapsd_bk&BIT(1);
2324                        break;
2325                case 4:
2326                case 5:
2327                        wmmps_ac = psta->uapsd_vi&BIT(1);
2328                        break;
2329                case 6:
2330                case 7:
2331                        wmmps_ac = psta->uapsd_vo&BIT(1);
2332                        break;
2333                case 0:
2334                case 3:
2335                default:
2336                        wmmps_ac = psta->uapsd_be&BIT(1);
2337                        break;
2338                }
2339
2340                if (!wmmps_ac)
2341                        continue;
2342
2343                list_del_init(&pxmitframe->list);
2344
2345                psta->sleepq_len--;
2346                psta->sleepq_ac_len--;
2347
2348                if (psta->sleepq_ac_len > 0) {
2349                        pxmitframe->attrib.mdata = 1;
2350                        pxmitframe->attrib.eosp = 0;
2351                } else {
2352                        pxmitframe->attrib.mdata = 0;
2353                        pxmitframe->attrib.eosp = 1;
2354                }
2355
2356                pxmitframe->attrib.triggered = 1;
2357                rtw_hal_xmitframe_enqueue(padapter, pxmitframe);
2358
2359                if ((psta->sleepq_ac_len == 0) && (!psta->has_legacy_ac) && (wmmps_ac)) {
2360                        pstapriv->tim_bitmap &= ~BIT(psta->aid);
2361
2362                        update_beacon(padapter, WLAN_EID_TIM, NULL, true);
2363                }
2364        }
2365
2366        spin_unlock_bh(&pxmitpriv->lock);
2367}
2368
2369void enqueue_pending_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2370{
2371        struct __queue *pqueue;
2372        struct adapter *pri_adapter = pxmitpriv->adapter;
2373
2374        pqueue = &pxmitpriv->pending_xmitbuf_queue;
2375
2376        spin_lock_bh(&pqueue->lock);
2377        list_del_init(&pxmitbuf->list);
2378        list_add_tail(&pxmitbuf->list, get_list_head(pqueue));
2379        spin_unlock_bh(&pqueue->lock);
2380
2381        complete(&pri_adapter->xmitpriv.xmit_comp);
2382}
2383
2384void enqueue_pending_xmitbuf_to_head(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
2385{
2386        struct __queue *pqueue;
2387
2388        pqueue = &pxmitpriv->pending_xmitbuf_queue;
2389
2390        spin_lock_bh(&pqueue->lock);
2391        list_del_init(&pxmitbuf->list);
2392        list_add(&pxmitbuf->list, get_list_head(pqueue));
2393        spin_unlock_bh(&pqueue->lock);
2394}
2395
2396struct xmit_buf *dequeue_pending_xmitbuf(struct xmit_priv *pxmitpriv)
2397{
2398        struct xmit_buf *pxmitbuf;
2399        struct __queue *pqueue;
2400
2401        pxmitbuf = NULL;
2402        pqueue = &pxmitpriv->pending_xmitbuf_queue;
2403
2404        spin_lock_bh(&pqueue->lock);
2405
2406        if (!list_empty(&pqueue->queue)) {
2407                struct list_head *plist, *phead;
2408
2409                phead = get_list_head(pqueue);
2410                plist = get_next(phead);
2411                pxmitbuf = container_of(plist, struct xmit_buf, list);
2412                list_del_init(&pxmitbuf->list);
2413        }
2414
2415        spin_unlock_bh(&pqueue->lock);
2416
2417        return pxmitbuf;
2418}
2419
2420struct xmit_buf *dequeue_pending_xmitbuf_under_survey(struct xmit_priv *pxmitpriv)
2421{
2422        struct xmit_buf *pxmitbuf;
2423        struct __queue *pqueue;
2424
2425        pxmitbuf = NULL;
2426        pqueue = &pxmitpriv->pending_xmitbuf_queue;
2427
2428        spin_lock_bh(&pqueue->lock);
2429
2430        if (!list_empty(&pqueue->queue)) {
2431                struct list_head *plist, *phead;
2432                u8 type;
2433
2434                phead = get_list_head(pqueue);
2435                plist = phead;
2436                do {
2437                        plist = get_next(plist);
2438                        if (plist == phead)
2439                                break;
2440
2441                        pxmitbuf = container_of(plist, struct xmit_buf, list);
2442
2443                        type = GetFrameSubType(pxmitbuf->pbuf + TXDESC_OFFSET);
2444
2445                        if ((type == WIFI_PROBEREQ) ||
2446                                (type == WIFI_DATA_NULL) ||
2447                                (type == WIFI_QOS_DATA_NULL)) {
2448                                list_del_init(&pxmitbuf->list);
2449                                break;
2450                        }
2451                        pxmitbuf = NULL;
2452                } while (1);
2453        }
2454
2455        spin_unlock_bh(&pqueue->lock);
2456
2457        return pxmitbuf;
2458}
2459
2460signed int check_pending_xmitbuf(struct xmit_priv *pxmitpriv)
2461{
2462        struct __queue *pqueue;
2463        signed int      ret = false;
2464
2465        pqueue = &pxmitpriv->pending_xmitbuf_queue;
2466
2467        spin_lock_bh(&pqueue->lock);
2468
2469        if (!list_empty(&pqueue->queue))
2470                ret = true;
2471
2472        spin_unlock_bh(&pqueue->lock);
2473
2474        return ret;
2475}
2476
2477int rtw_xmit_thread(void *context)
2478{
2479        s32 err;
2480        struct adapter *padapter;
2481
2482        err = _SUCCESS;
2483        padapter = context;
2484
2485        thread_enter("RTW_XMIT_THREAD");
2486
2487        do {
2488                err = rtw_hal_xmit_thread_handler(padapter);
2489                flush_signals_thread();
2490        } while (err == _SUCCESS);
2491
2492        complete(&padapter->xmitpriv.terminate_xmitthread_comp);
2493
2494        thread_exit();
2495}
2496
2497void rtw_sctx_init(struct submit_ctx *sctx, int timeout_ms)
2498{
2499        sctx->timeout_ms = timeout_ms;
2500        sctx->submit_time = jiffies;
2501        init_completion(&sctx->done);
2502        sctx->status = RTW_SCTX_SUBMITTED;
2503}
2504
2505int rtw_sctx_wait(struct submit_ctx *sctx)
2506{
2507        int ret = _FAIL;
2508        unsigned long expire;
2509        int status = 0;
2510
2511        expire = sctx->timeout_ms ? msecs_to_jiffies(sctx->timeout_ms) : MAX_SCHEDULE_TIMEOUT;
2512        if (!wait_for_completion_timeout(&sctx->done, expire))
2513                /* timeout, do something?? */
2514                status = RTW_SCTX_DONE_TIMEOUT;
2515        else
2516                status = sctx->status;
2517
2518        if (status == RTW_SCTX_DONE_SUCCESS)
2519                ret = _SUCCESS;
2520
2521        return ret;
2522}
2523
2524void rtw_sctx_done_err(struct submit_ctx **sctx, int status)
2525{
2526        if (*sctx) {
2527                (*sctx)->status = status;
2528                complete(&((*sctx)->done));
2529                *sctx = NULL;
2530        }
2531}
2532
2533void rtw_sctx_done(struct submit_ctx **sctx)
2534{
2535        rtw_sctx_done_err(sctx, RTW_SCTX_DONE_SUCCESS);
2536}
2537
2538int rtw_ack_tx_wait(struct xmit_priv *pxmitpriv, u32 timeout_ms)
2539{
2540        struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2541
2542        pack_tx_ops->submit_time = jiffies;
2543        pack_tx_ops->timeout_ms = timeout_ms;
2544        pack_tx_ops->status = RTW_SCTX_SUBMITTED;
2545
2546        return rtw_sctx_wait(pack_tx_ops);
2547}
2548
2549void rtw_ack_tx_done(struct xmit_priv *pxmitpriv, int status)
2550{
2551        struct submit_ctx *pack_tx_ops = &pxmitpriv->ack_tx_ops;
2552
2553        if (pxmitpriv->ack_tx)
2554                rtw_sctx_done_err(&pack_tx_ops, status);
2555}
2556