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