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