linux/drivers/staging/rtl8712/rtl871x_xmit.c
<<
>>
Prefs
   1/******************************************************************************
   2 * rtl871x_xmit.c
   3 *
   4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
   5 * Linux device driver for RTL8192SU
   6 *
   7 * This program is free software; you can redistribute it and/or modify it
   8 * under the terms of version 2 of the GNU General Public License as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful, but WITHOUT
  12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  14 * more details.
  15 *
  16 * You should have received a copy of the GNU General Public License along with
  17 * this program; if not, write to the Free Software Foundation, Inc.,
  18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  19 *
  20 * Modifications for inclusion into the Linux staging tree are
  21 * Copyright(c) 2010 Larry Finger. All rights reserved.
  22 *
  23 * Contact information:
  24 * WLAN FAE <wlanfae@realtek.com>
  25 * Larry Finger <Larry.Finger@lwfinger.net>
  26 *
  27 ******************************************************************************/
  28
  29#define _RTL871X_XMIT_C_
  30
  31#include "osdep_service.h"
  32#include "drv_types.h"
  33#include "wifi.h"
  34#include "osdep_intf.h"
  35#include "usb_ops.h"
  36
  37
  38static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
  39static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
  40static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
  41static void alloc_hwxmits(struct _adapter *padapter);
  42static void free_hwxmits(struct _adapter *padapter);
  43
  44static void _init_txservq(struct tx_servq *ptxservq)
  45{
  46        INIT_LIST_HEAD(&ptxservq->tx_pending);
  47        _init_queue(&ptxservq->sta_pending);
  48        ptxservq->qcnt = 0;
  49}
  50
  51void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
  52{
  53        memset((unsigned char *)psta_xmitpriv, 0,
  54                 sizeof(struct sta_xmit_priv));
  55        spin_lock_init(&psta_xmitpriv->lock);
  56        _init_txservq(&psta_xmitpriv->be_q);
  57        _init_txservq(&psta_xmitpriv->bk_q);
  58        _init_txservq(&psta_xmitpriv->vi_q);
  59        _init_txservq(&psta_xmitpriv->vo_q);
  60        INIT_LIST_HEAD(&psta_xmitpriv->legacy_dz);
  61        INIT_LIST_HEAD(&psta_xmitpriv->apsd);
  62}
  63
  64sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
  65                           struct _adapter *padapter)
  66{
  67        sint i;
  68        struct xmit_buf *pxmitbuf;
  69        struct xmit_frame *pxframe;
  70
  71        memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
  72        spin_lock_init(&pxmitpriv->lock);
  73        /*
  74         *Please insert all the queue initialization using _init_queue below
  75         */
  76        pxmitpriv->adapter = padapter;
  77        _init_queue(&pxmitpriv->be_pending);
  78        _init_queue(&pxmitpriv->bk_pending);
  79        _init_queue(&pxmitpriv->vi_pending);
  80        _init_queue(&pxmitpriv->vo_pending);
  81        _init_queue(&pxmitpriv->bm_pending);
  82        _init_queue(&pxmitpriv->legacy_dz_queue);
  83        _init_queue(&pxmitpriv->apsd_queue);
  84        _init_queue(&pxmitpriv->free_xmit_queue);
  85        /*
  86         * Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
  87         * and initialize free_xmit_frame below.
  88         * Please also apply  free_txobj to link_up all the xmit_frames...
  89         */
  90        pxmitpriv->pallocated_frame_buf = kmalloc(NR_XMITFRAME * sizeof(struct xmit_frame) + 4,
  91                                                  GFP_ATOMIC);
  92        if (!pxmitpriv->pallocated_frame_buf) {
  93                pxmitpriv->pxmit_frame_buf = NULL;
  94                return _FAIL;
  95        }
  96        pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
  97                        ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
  98        pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
  99        for (i = 0; i < NR_XMITFRAME; i++) {
 100                INIT_LIST_HEAD(&(pxframe->list));
 101                pxframe->padapter = padapter;
 102                pxframe->frame_tag = DATA_FRAMETAG;
 103                pxframe->pkt = NULL;
 104                pxframe->buf_addr = NULL;
 105                pxframe->pxmitbuf = NULL;
 106                list_add_tail(&(pxframe->list),
 107                                 &(pxmitpriv->free_xmit_queue.queue));
 108                pxframe++;
 109        }
 110        pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
 111        /*
 112         * init xmit hw_txqueue
 113         */
 114        _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
 115        _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
 116        _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
 117        _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
 118        _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
 119        pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
 120        pxmitpriv->txirp_cnt = 1;
 121        /*per AC pending irp*/
 122        pxmitpriv->beq_cnt = 0;
 123        pxmitpriv->bkq_cnt = 0;
 124        pxmitpriv->viq_cnt = 0;
 125        pxmitpriv->voq_cnt = 0;
 126        /*init xmit_buf*/
 127        _init_queue(&pxmitpriv->free_xmitbuf_queue);
 128        _init_queue(&pxmitpriv->pending_xmitbuf_queue);
 129        pxmitpriv->pallocated_xmitbuf = kmalloc(NR_XMITBUFF * sizeof(struct xmit_buf) + 4,
 130                                                GFP_ATOMIC);
 131        if (!pxmitpriv->pallocated_xmitbuf) {
 132                kfree(pxmitpriv->pallocated_frame_buf);
 133                pxmitpriv->pallocated_frame_buf = NULL;
 134                return _FAIL;
 135        }
 136        pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
 137                              ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
 138        pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 139        for (i = 0; i < NR_XMITBUFF; i++) {
 140                INIT_LIST_HEAD(&pxmitbuf->list);
 141                pxmitbuf->pallocated_buf = kmalloc(MAX_XMITBUF_SZ + XMITBUF_ALIGN_SZ,
 142                                                   GFP_ATOMIC);
 143                if (!pxmitbuf->pallocated_buf)
 144                        return _FAIL;
 145                pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
 146                                 ((addr_t) (pxmitbuf->pallocated_buf) &
 147                                 (XMITBUF_ALIGN_SZ - 1));
 148                r8712_xmit_resource_alloc(padapter, pxmitbuf);
 149                list_add_tail(&pxmitbuf->list,
 150                                 &(pxmitpriv->free_xmitbuf_queue.queue));
 151                pxmitbuf++;
 152        }
 153        pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
 154        INIT_WORK(&padapter->wkFilterRxFF0, r8712_SetFilter);
 155        alloc_hwxmits(padapter);
 156        init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 157        tasklet_init(&pxmitpriv->xmit_tasklet,
 158                (void(*)(unsigned long))r8712_xmit_bh,
 159                (unsigned long)padapter);
 160        return _SUCCESS;
 161}
 162
 163void _free_xmit_priv(struct xmit_priv *pxmitpriv)
 164{
 165        int i;
 166        struct _adapter *padapter = pxmitpriv->adapter;
 167        struct xmit_frame *pxmitframe = (struct xmit_frame *)
 168                                        pxmitpriv->pxmit_frame_buf;
 169        struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
 170
 171        if (pxmitpriv->pxmit_frame_buf == NULL)
 172                return;
 173        for (i = 0; i < NR_XMITFRAME; i++) {
 174                r8712_xmit_complete(padapter, pxmitframe);
 175                pxmitframe++;
 176        }
 177        for (i = 0; i < NR_XMITBUFF; i++) {
 178                r8712_xmit_resource_free(padapter, pxmitbuf);
 179                kfree(pxmitbuf->pallocated_buf);
 180                pxmitbuf++;
 181        }
 182        kfree(pxmitpriv->pallocated_frame_buf);
 183        kfree(pxmitpriv->pallocated_xmitbuf);
 184        free_hwxmits(padapter);
 185}
 186
 187sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
 188                   struct pkt_attrib *pattrib)
 189{
 190        struct pkt_file pktfile;
 191        struct sta_info *psta = NULL;
 192        struct ethhdr etherhdr;
 193
 194        struct tx_cmd txdesc;
 195
 196        sint bmcast;
 197        struct sta_priv         *pstapriv = &padapter->stapriv;
 198        struct security_priv    *psecuritypriv = &padapter->securitypriv;
 199        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 200        struct qos_priv         *pqospriv = &pmlmepriv->qospriv;
 201
 202        _r8712_open_pktfile(pkt, &pktfile);
 203
 204        _r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);
 205
 206        pattrib->ether_type = ntohs(etherhdr.h_proto);
 207
 208{
 209        /*If driver xmit ARP packet, driver can set ps mode to initial
 210         * setting. It stands for getting DHCP or fix IP.
 211         */
 212        if (pattrib->ether_type == 0x0806) {
 213                if (padapter->pwrctrlpriv.pwr_mode !=
 214                    padapter->registrypriv.power_mgnt) {
 215                        del_timer_sync(&pmlmepriv->dhcp_timer);
 216                        r8712_set_ps_mode(padapter,
 217                                          padapter->registrypriv.power_mgnt,
 218                                          padapter->registrypriv.smart_ps);
 219                }
 220        }
 221}
 222        memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
 223        memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
 224        pattrib->pctrl = 0;
 225        if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 226            check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
 227                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 228                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 229        } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
 230                memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
 231                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 232        } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 233                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 234                memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
 235        } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 236                /*firstly, filter packet not belongs to mp*/
 237                if (pattrib->ether_type != 0x8712)
 238                        return _FAIL;
 239                /* for mp storing the txcmd per packet,
 240                 * according to the info of txcmd to update pattrib
 241                 */
 242                /*get MP_TXDESC_SIZE bytes txcmd per packet*/
 243                _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
 244                memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
 245                memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
 246                pattrib->pctrl = 1;
 247        }
 248        /* r8712_xmitframe_coalesce() overwrite this!*/
 249        pattrib->pktlen = pktfile.pkt_len;
 250        if (pattrib->ether_type == ETH_P_IP) {
 251                /* The following is for DHCP and ARP packet, we use cck1M to
 252                 * tx these packets and let LPS awake some time
 253                 * to prevent DHCP protocol fail
 254                 */
 255                u8 tmp[24];
 256
 257                _r8712_pktfile_read(&pktfile, &tmp[0], 24);
 258                pattrib->dhcp_pkt = 0;
 259                if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
 260                        if (pattrib->ether_type == ETH_P_IP) {/* IP header*/
 261                                if (((tmp[21] == 68) && (tmp[23] == 67)) ||
 262                                        ((tmp[21] == 67) && (tmp[23] == 68))) {
 263                                        /* 68 : UDP BOOTP client
 264                                         * 67 : UDP BOOTP server
 265                                         * Use low rate to send DHCP packet.
 266                                         */
 267                                        pattrib->dhcp_pkt = 1;
 268                                }
 269                        }
 270                }
 271        }
 272        bmcast = IS_MCAST(pattrib->ra);
 273        /* get sta_info*/
 274        if (bmcast) {
 275                psta = r8712_get_bcmc_stainfo(padapter);
 276                pattrib->mac_id = 4;
 277        } else {
 278                if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 279                        psta = r8712_get_stainfo(pstapriv,
 280                                                 get_bssid(pmlmepriv));
 281                        pattrib->mac_id = 5;
 282                } else {
 283                        psta = r8712_get_stainfo(pstapriv, pattrib->ra);
 284                        if (psta == NULL)  /* drop the pkt */
 285                                return _FAIL;
 286                        if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
 287                                pattrib->mac_id = 5;
 288                        else
 289                                pattrib->mac_id = psta->mac_id;
 290                }
 291        }
 292
 293        if (psta) {
 294                pattrib->psta = psta;
 295        } else {
 296                /* if we cannot get psta => drrp the pkt */
 297                return _FAIL;
 298        }
 299
 300        pattrib->ack_policy = 0;
 301        /* get ether_hdr_len */
 302        pattrib->pkt_hdrlen = ETH_HLEN;
 303
 304        if (pqospriv->qos_option) {
 305                r8712_set_qos(&pktfile, pattrib);
 306        } else {
 307                pattrib->hdrlen = WLAN_HDR_A3_LEN;
 308                pattrib->subtype = WIFI_DATA_TYPE;
 309                pattrib->priority = 0;
 310        }
 311        if (psta->ieee8021x_blocked) {
 312                pattrib->encrypt = 0;
 313                if ((pattrib->ether_type != 0x888e) &&
 314                    !check_fwstate(pmlmepriv, WIFI_MP_STATE))
 315                        return _FAIL;
 316        } else {
 317                GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
 318        }
 319        switch (pattrib->encrypt) {
 320        case _WEP40_:
 321        case _WEP104_:
 322                pattrib->iv_len = 4;
 323                pattrib->icv_len = 4;
 324                break;
 325        case _TKIP_:
 326                pattrib->iv_len = 8;
 327                pattrib->icv_len = 4;
 328                if (padapter->securitypriv.busetkipkey == _FAIL)
 329                        return _FAIL;
 330                break;
 331        case _AES_:
 332                pattrib->iv_len = 8;
 333                pattrib->icv_len = 8;
 334                break;
 335        default:
 336                pattrib->iv_len = 0;
 337                pattrib->icv_len = 0;
 338                break;
 339        }
 340
 341        if (pattrib->encrypt &&
 342            (padapter->securitypriv.sw_encrypt ||
 343            !psecuritypriv->hw_decrypted))
 344                pattrib->bswenc = true;
 345        else
 346                pattrib->bswenc = false;
 347        /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
 348         * some settings above.
 349         */
 350        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 351                pattrib->priority =
 352                    (le32_to_cpu(txdesc.txdw1) >> QSEL_SHT) & 0x1f;
 353        return _SUCCESS;
 354}
 355
 356static sint xmitframe_addmic(struct _adapter *padapter,
 357                             struct xmit_frame *pxmitframe)
 358{
 359        u32     curfragnum, length;
 360        u8      *pframe, *payload, mic[8];
 361        struct  mic_data micdata;
 362        struct  sta_info *stainfo;
 363        struct  qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
 364        struct  pkt_attrib  *pattrib = &pxmitframe->attrib;
 365        struct  security_priv *psecuritypriv = &padapter->securitypriv;
 366        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 367        u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
 368        sint bmcst = IS_MCAST(pattrib->ra);
 369
 370        if (pattrib->psta)
 371                stainfo = pattrib->psta;
 372        else
 373                stainfo = r8712_get_stainfo(&padapter->stapriv,
 374                                            &pattrib->ra[0]);
 375        if (pattrib->encrypt == _TKIP_) {
 376                /*encode mic code*/
 377                if (stainfo != NULL) {
 378                        u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 379                                           0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
 380                                           0x0, 0x0};
 381                        pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
 382                        if (bmcst) {
 383                                if (!memcmp(psecuritypriv->XGrptxmickey
 384                                   [psecuritypriv->XGrpKeyid].skey,
 385                                   null_key, 16))
 386                                        return _FAIL;
 387                                /*start to calculate the mic code*/
 388                                r8712_secmicsetkey(&micdata,
 389                                         psecuritypriv->
 390                                         XGrptxmickey[psecuritypriv->
 391                                        XGrpKeyid].skey);
 392                        } else {
 393                                if (!memcmp(&stainfo->tkiptxmickey.skey[0],
 394                                            null_key, 16))
 395                                        return _FAIL;
 396                                /* start to calculate the mic code */
 397                                r8712_secmicsetkey(&micdata,
 398                                             &stainfo->tkiptxmickey.skey[0]);
 399                        }
 400                        if (pframe[1] & 1) {   /* ToDS==1 */
 401                                r8712_secmicappend(&micdata,
 402                                                   &pframe[16], 6); /*DA*/
 403                                if (pframe[1] & 2)  /* From Ds==1 */
 404                                        r8712_secmicappend(&micdata,
 405                                                           &pframe[24], 6);
 406                                else
 407                                        r8712_secmicappend(&micdata,
 408                                                           &pframe[10], 6);
 409                        } else {        /* ToDS==0 */
 410                                r8712_secmicappend(&micdata,
 411                                                   &pframe[4], 6); /* DA */
 412                                if (pframe[1] & 2)  /* From Ds==1 */
 413                                        r8712_secmicappend(&micdata,
 414                                                           &pframe[16], 6);
 415                                else
 416                                        r8712_secmicappend(&micdata,
 417                                                           &pframe[10], 6);
 418                        }
 419                        if (pqospriv->qos_option == 1)
 420                                priority[0] = (u8)pxmitframe->attrib.priority;
 421                        r8712_secmicappend(&micdata, &priority[0], 4);
 422                        payload = pframe;
 423                        for (curfragnum = 0; curfragnum < pattrib->nr_frags;
 424                             curfragnum++) {
 425                                payload = (u8 *)RND4((addr_t)(payload));
 426                                payload += pattrib->hdrlen + pattrib->iv_len;
 427                                if ((curfragnum + 1) == pattrib->nr_frags) {
 428                                        length = pattrib->last_txcmdsz -
 429                                                  pattrib->hdrlen -
 430                                                  pattrib->iv_len -
 431                                                  ((psecuritypriv->sw_encrypt)
 432                                                  ? pattrib->icv_len : 0);
 433                                        r8712_secmicappend(&micdata, payload,
 434                                                           length);
 435                                        payload = payload + length;
 436                                } else{
 437                                        length = pxmitpriv->frag_len -
 438                                            pattrib->hdrlen - pattrib->iv_len -
 439                                            ((psecuritypriv->sw_encrypt) ?
 440                                            pattrib->icv_len : 0);
 441                                        r8712_secmicappend(&micdata, payload,
 442                                                           length);
 443                                        payload = payload + length +
 444                                                  pattrib->icv_len;
 445                                }
 446                        }
 447                        r8712_secgetmic(&micdata, &(mic[0]));
 448                        /* add mic code  and add the mic code length in
 449                         * last_txcmdsz
 450                         */
 451                        memcpy(payload, &(mic[0]), 8);
 452                        pattrib->last_txcmdsz += 8;
 453                        payload = payload - pattrib->last_txcmdsz + 8;
 454                }
 455        }
 456        return _SUCCESS;
 457}
 458
 459static sint xmitframe_swencrypt(struct _adapter *padapter,
 460                                struct xmit_frame *pxmitframe)
 461{
 462        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 463
 464        if (pattrib->bswenc) {
 465                switch (pattrib->encrypt) {
 466                case _WEP40_:
 467                case _WEP104_:
 468                        r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
 469                        break;
 470                case _TKIP_:
 471                        r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
 472                        break;
 473                case _AES_:
 474                        r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
 475                        break;
 476                default:
 477                                break;
 478                }
 479        }
 480        return _SUCCESS;
 481}
 482
 483static sint make_wlanhdr(struct _adapter *padapter, u8 *hdr,
 484                         struct pkt_attrib *pattrib)
 485{
 486        u16 *qc;
 487
 488        struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
 489        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 490        struct qos_priv *pqospriv = &pmlmepriv->qospriv;
 491        __le16 *fctrl = &pwlanhdr->frame_ctl;
 492
 493        memset(hdr, 0, WLANHDR_OFFSET);
 494        SetFrameSubType(fctrl, pattrib->subtype);
 495        if (pattrib->subtype & WIFI_DATA_TYPE) {
 496                if (check_fwstate(pmlmepriv,  WIFI_STATION_STATE)) {
 497                        /* to_ds = 1, fr_ds = 0; */
 498                        SetToDs(fctrl);
 499                        memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
 500                                ETH_ALEN);
 501                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 502                        memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
 503                } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
 504                        /* to_ds = 0, fr_ds = 1; */
 505                        SetFrDs(fctrl);
 506                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 507                        memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
 508                                ETH_ALEN);
 509                        memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
 510                } else if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
 511                           check_fwstate(pmlmepriv,
 512                                         WIFI_ADHOC_MASTER_STATE)) {
 513                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 514                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 515                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
 516                                ETH_ALEN);
 517                } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 518                        memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
 519                        memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
 520                        memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
 521                                ETH_ALEN);
 522                } else {
 523                        return _FAIL;
 524                }
 525
 526                if (pattrib->encrypt)
 527                        SetPrivacy(fctrl);
 528                if (pqospriv->qos_option) {
 529                        qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
 530                        if (pattrib->priority)
 531                                SetPriority(qc, pattrib->priority);
 532                        SetAckpolicy(qc, pattrib->ack_policy);
 533                }
 534                /* TODO: fill HT Control Field */
 535                /* Update Seq Num will be handled by f/w */
 536                {
 537                        struct sta_info *psta;
 538                        sint bmcst = IS_MCAST(pattrib->ra);
 539
 540                        if (pattrib->psta) {
 541                                psta = pattrib->psta;
 542                        } else {
 543                                if (bmcst)
 544                                        psta = r8712_get_bcmc_stainfo(padapter);
 545                                else
 546                                        psta =
 547                                         r8712_get_stainfo(&padapter->stapriv,
 548                                         pattrib->ra);
 549                        }
 550                        if (psta) {
 551                                psta->sta_xmitpriv.txseq_tid
 552                                                  [pattrib->priority]++;
 553                                psta->sta_xmitpriv.txseq_tid[pattrib->priority]
 554                                                   &= 0xFFF;
 555                                pattrib->seqnum = psta->sta_xmitpriv.
 556                                                  txseq_tid[pattrib->priority];
 557                                SetSeqNum(hdr, pattrib->seqnum);
 558                        }
 559                }
 560        }
 561        return _SUCCESS;
 562}
 563
 564static sint r8712_put_snap(u8 *data, u16 h_proto)
 565{
 566        struct ieee80211_snap_hdr *snap;
 567        const u8 *oui;
 568
 569        snap = (struct ieee80211_snap_hdr *)data;
 570        snap->dsap = 0xaa;
 571        snap->ssap = 0xaa;
 572        snap->ctrl = 0x03;
 573        if (h_proto == 0x8137 || h_proto == 0x80f3)
 574                oui = P802_1H_OUI;
 575        else
 576                oui = RFC1042_OUI;
 577        snap->oui[0] = oui[0];
 578        snap->oui[1] = oui[1];
 579        snap->oui[2] = oui[2];
 580        *(__be16 *)(data + SNAP_SIZE) = htons(h_proto);
 581        return SNAP_SIZE + sizeof(u16);
 582}
 583
 584/*
 585 * This sub-routine will perform all the following:
 586 * 1. remove 802.3 header.
 587 * 2. create wlan_header, based on the info in pxmitframe
 588 * 3. append sta's iv/ext-iv
 589 * 4. append LLC
 590 * 5. move frag chunk from pframe to pxmitframe->mem
 591 * 6. apply sw-encrypt, if necessary.
 592 */
 593sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
 594                        struct xmit_frame *pxmitframe)
 595{
 596        struct pkt_file pktfile;
 597
 598        sint    frg_len, mpdu_len, llc_sz;
 599        u32     mem_sz;
 600        u8      frg_inx;
 601        addr_t addr;
 602        u8 *pframe, *mem_start, *ptxdesc;
 603        struct sta_info         *psta;
 604        struct security_priv    *psecuritypriv = &padapter->securitypriv;
 605        struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;
 606        struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
 607        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 608        u8 *pbuf_start;
 609        sint bmcst = IS_MCAST(pattrib->ra);
 610
 611        if (pattrib->psta == NULL)
 612                return _FAIL;
 613        psta = pattrib->psta;
 614        if (pxmitframe->buf_addr == NULL)
 615                return _FAIL;
 616        pbuf_start = pxmitframe->buf_addr;
 617        ptxdesc = pbuf_start;
 618        mem_start = pbuf_start + TXDESC_OFFSET;
 619        if (make_wlanhdr(padapter, mem_start, pattrib) == _FAIL)
 620                return _FAIL;
 621        _r8712_open_pktfile(pkt, &pktfile);
 622        _r8712_pktfile_read(&pktfile, NULL, (uint) pattrib->pkt_hdrlen);
 623        if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
 624                /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
 625                if (pattrib->ether_type == 0x8712) {
 626                        /* take care -  update_txdesc overwrite this */
 627                        _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
 628                }
 629        }
 630        pattrib->pktlen = pktfile.pkt_len;
 631        frg_inx = 0;
 632        frg_len = pxmitpriv->frag_len - 4;
 633        while (1) {
 634                llc_sz = 0;
 635                mpdu_len = frg_len;
 636                pframe = mem_start;
 637                SetMFrag(mem_start);
 638                pframe += pattrib->hdrlen;
 639                mpdu_len -= pattrib->hdrlen;
 640                /* adding icv, if necessary...*/
 641                if (pattrib->iv_len) {
 642                        if (psta != NULL) {
 643                                switch (pattrib->encrypt) {
 644                                case _WEP40_:
 645                                case _WEP104_:
 646                                        WEP_IV(pattrib->iv, psta->txpn,
 647                                               (u8)psecuritypriv->
 648                                               PrivacyKeyIndex);
 649                                        break;
 650                                case _TKIP_:
 651                                        if (bmcst)
 652                                                TKIP_IV(pattrib->iv,
 653                                                    psta->txpn,
 654                                                    (u8)psecuritypriv->
 655                                                    XGrpKeyid);
 656                                        else
 657                                                TKIP_IV(pattrib->iv, psta->txpn,
 658                                                        0);
 659                                        break;
 660                                case _AES_:
 661                                        if (bmcst)
 662                                                AES_IV(pattrib->iv, psta->txpn,
 663                                                    (u8)psecuritypriv->
 664                                                    XGrpKeyid);
 665                                        else
 666                                                AES_IV(pattrib->iv, psta->txpn,
 667                                                       0);
 668                                        break;
 669                                }
 670                        }
 671                        memcpy(pframe, pattrib->iv, pattrib->iv_len);
 672                        pframe += pattrib->iv_len;
 673                        mpdu_len -= pattrib->iv_len;
 674                }
 675                if (frg_inx == 0) {
 676                        llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
 677                        pframe += llc_sz;
 678                        mpdu_len -= llc_sz;
 679                }
 680                if ((pattrib->icv_len > 0) && (pattrib->bswenc))
 681                        mpdu_len -= pattrib->icv_len;
 682                if (bmcst)
 683                        mem_sz = _r8712_pktfile_read(&pktfile, pframe,
 684                                 pattrib->pktlen);
 685                else
 686                        mem_sz = _r8712_pktfile_read(&pktfile, pframe,
 687                                 mpdu_len);
 688                pframe += mem_sz;
 689                if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
 690                        memcpy(pframe, pattrib->icv, pattrib->icv_len);
 691                        pframe += pattrib->icv_len;
 692                }
 693                frg_inx++;
 694                if (bmcst || r8712_endofpktfile(&pktfile)) {
 695                        pattrib->nr_frags = frg_inx;
 696                        pattrib->last_txcmdsz = pattrib->hdrlen +
 697                                                pattrib->iv_len +
 698                                                ((pattrib->nr_frags == 1) ?
 699                                                llc_sz : 0) +
 700                                                ((pattrib->bswenc) ?
 701                                                pattrib->icv_len : 0) + mem_sz;
 702                        ClearMFrag(mem_start);
 703                        break;
 704                }
 705                addr = (addr_t)(pframe);
 706                mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
 707                memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
 708        }
 709
 710        if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
 711                return _FAIL;
 712        xmitframe_swencrypt(padapter, pxmitframe);
 713        return _SUCCESS;
 714}
 715
 716void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
 717{
 718        uint    protection;
 719        u8      *perp;
 720        uint    erp_len;
 721        struct  xmit_priv *pxmitpriv = &padapter->xmitpriv;
 722        struct  registry_priv *pregistrypriv = &padapter->registrypriv;
 723
 724        switch (pxmitpriv->vcs_setting) {
 725        case DISABLE_VCS:
 726                pxmitpriv->vcs = NONE_VCS;
 727                break;
 728        case ENABLE_VCS:
 729                break;
 730        case AUTO_VCS:
 731        default:
 732                perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
 733                if (perp == NULL) {
 734                        pxmitpriv->vcs = NONE_VCS;
 735                } else {
 736                        protection = (*(perp + 2)) & BIT(1);
 737                        if (protection) {
 738                                if (pregistrypriv->vcs_type == RTS_CTS)
 739                                        pxmitpriv->vcs = RTS_CTS;
 740                                else
 741                                        pxmitpriv->vcs = CTS_TO_SELF;
 742                        } else {
 743                                pxmitpriv->vcs = NONE_VCS;
 744                        }
 745                }
 746                break;
 747        }
 748}
 749
 750struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
 751{
 752        unsigned long irqL;
 753        struct xmit_buf *pxmitbuf;
 754        struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 755
 756        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
 757        pxmitbuf = list_first_entry_or_null(&pfree_xmitbuf_queue->queue,
 758                                            struct xmit_buf, list);
 759        if (pxmitbuf) {
 760                list_del_init(&pxmitbuf->list);
 761                pxmitpriv->free_xmitbuf_cnt--;
 762        }
 763        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
 764        return pxmitbuf;
 765}
 766
 767int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
 768{
 769        unsigned long irqL;
 770        struct  __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
 771
 772        if (pxmitbuf == NULL)
 773                return _FAIL;
 774        spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
 775        list_del_init(&pxmitbuf->list);
 776        list_add_tail(&(pxmitbuf->list), &pfree_xmitbuf_queue->queue);
 777        pxmitpriv->free_xmitbuf_cnt++;
 778        spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
 779        return _SUCCESS;
 780}
 781
 782/*
 783 * Calling context:
 784 * 1. OS_TXENTRY
 785 * 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
 786 *
 787 * If we turn on USE_RXTHREAD, then, no need for critical section.
 788 * Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
 789 *
 790 * Must be very very cautious...
 791 *
 792 */
 793struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
 794{
 795        /*
 796         * Please remember to use all the osdep_service api,
 797         * and lock/unlock or _enter/_exit critical to protect
 798         * pfree_xmit_queue
 799         */
 800        unsigned long irqL;
 801        struct xmit_frame *pxframe;
 802        struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
 803
 804        spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
 805        pxframe = list_first_entry_or_null(&pfree_xmit_queue->queue,
 806                                           struct xmit_frame, list);
 807        if (pxframe) {
 808                list_del_init(&pxframe->list);
 809                pxmitpriv->free_xmitframe_cnt--;
 810                pxframe->buf_addr = NULL;
 811                pxframe->pxmitbuf = NULL;
 812                pxframe->attrib.psta = NULL;
 813                pxframe->pkt = NULL;
 814        }
 815        spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
 816        return pxframe;
 817}
 818
 819void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
 820                          struct xmit_frame *pxmitframe)
 821{
 822        unsigned long irqL;
 823        struct  __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
 824        struct _adapter *padapter = pxmitpriv->adapter;
 825
 826        if (pxmitframe == NULL)
 827                return;
 828        spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
 829        list_del_init(&pxmitframe->list);
 830        if (pxmitframe->pkt)
 831                pxmitframe->pkt = NULL;
 832        list_add_tail(&pxmitframe->list, &pfree_xmit_queue->queue);
 833        pxmitpriv->free_xmitframe_cnt++;
 834        spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
 835        if (netif_queue_stopped(padapter->pnetdev))
 836                netif_wake_queue(padapter->pnetdev);
 837}
 838
 839void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
 840                      struct xmit_frame *pxmitframe)
 841{
 842        if (pxmitframe == NULL)
 843                return;
 844        if (pxmitframe->frame_tag == DATA_FRAMETAG)
 845                r8712_free_xmitframe(pxmitpriv, pxmitframe);
 846}
 847
 848void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
 849                                struct  __queue *pframequeue)
 850{
 851        unsigned long irqL;
 852        struct list_head *plist, *phead;
 853        struct  xmit_frame      *pxmitframe;
 854
 855        spin_lock_irqsave(&(pframequeue->lock), irqL);
 856        phead = &pframequeue->queue;
 857        plist = phead->next;
 858        while (!end_of_queue_search(phead, plist)) {
 859                pxmitframe = container_of(plist, struct xmit_frame, list);
 860                plist = plist->next;
 861                r8712_free_xmitframe(pxmitpriv, pxmitframe);
 862        }
 863        spin_unlock_irqrestore(&(pframequeue->lock), irqL);
 864}
 865
 866static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
 867                                               struct  __queue **ppstapending,
 868                                               struct sta_info *psta, sint up)
 869{
 870
 871        struct tx_servq *ptxservq;
 872        struct hw_xmit *phwxmits =  padapter->xmitpriv.hwxmits;
 873
 874        switch (up) {
 875        case 1:
 876        case 2:
 877                ptxservq = &(psta->sta_xmitpriv.bk_q);
 878                *ppstapending = &padapter->xmitpriv.bk_pending;
 879                (phwxmits + 3)->accnt++;
 880                break;
 881        case 4:
 882        case 5:
 883                ptxservq = &(psta->sta_xmitpriv.vi_q);
 884                *ppstapending = &padapter->xmitpriv.vi_pending;
 885                (phwxmits + 1)->accnt++;
 886                break;
 887        case 6:
 888        case 7:
 889                ptxservq = &(psta->sta_xmitpriv.vo_q);
 890                *ppstapending = &padapter->xmitpriv.vo_pending;
 891                (phwxmits + 0)->accnt++;
 892                break;
 893        case 0:
 894        case 3:
 895        default:
 896                ptxservq = &(psta->sta_xmitpriv.be_q);
 897                *ppstapending = &padapter->xmitpriv.be_pending;
 898                (phwxmits + 2)->accnt++;
 899                break;
 900        }
 901        return ptxservq;
 902}
 903
 904/*
 905 * Will enqueue pxmitframe to the proper queue, and indicate it
 906 * to xx_pending list.....
 907 */
 908sint r8712_xmit_classifier(struct _adapter *padapter,
 909                           struct xmit_frame *pxmitframe)
 910{
 911        unsigned long irqL0;
 912        struct  __queue *pstapending;
 913        struct sta_info *psta;
 914        struct tx_servq *ptxservq;
 915        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 916        struct sta_priv *pstapriv = &padapter->stapriv;
 917        struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 918        sint bmcst = IS_MCAST(pattrib->ra);
 919
 920        if (pattrib->psta) {
 921                psta = pattrib->psta;
 922        } else {
 923                if (bmcst) {
 924                        psta = r8712_get_bcmc_stainfo(padapter);
 925                } else {
 926                        if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
 927                                psta = r8712_get_stainfo(pstapriv,
 928                                       get_bssid(pmlmepriv));
 929                        else
 930                                psta = r8712_get_stainfo(pstapriv, pattrib->ra);
 931                }
 932        }
 933        if (psta == NULL)
 934                return _FAIL;
 935        ptxservq = get_sta_pending(padapter, &pstapending,
 936                   psta, pattrib->priority);
 937        spin_lock_irqsave(&pstapending->lock, irqL0);
 938        if (list_empty(&ptxservq->tx_pending))
 939                list_add_tail(&ptxservq->tx_pending, &pstapending->queue);
 940        list_add_tail(&pxmitframe->list, &ptxservq->sta_pending.queue);
 941        ptxservq->qcnt++;
 942        spin_unlock_irqrestore(&pstapending->lock, irqL0);
 943        return _SUCCESS;
 944}
 945
 946static void alloc_hwxmits(struct _adapter *padapter)
 947{
 948        struct hw_xmit *hwxmits;
 949        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 950
 951        pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
 952        pxmitpriv->hwxmits = kmalloc_array(pxmitpriv->hwxmit_entry,
 953                                sizeof(struct hw_xmit), GFP_ATOMIC);
 954        if (!pxmitpriv->hwxmits)
 955                return;
 956        hwxmits = pxmitpriv->hwxmits;
 957        if (pxmitpriv->hwxmit_entry == 5) {
 958                pxmitpriv->bmc_txqueue.head = 0;
 959                hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
 960                hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
 961                pxmitpriv->vo_txqueue.head = 0;
 962                hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
 963                hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
 964        pxmitpriv->vi_txqueue.head = 0;
 965                hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
 966                hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
 967                pxmitpriv->bk_txqueue.head = 0;
 968                hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
 969                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
 970                pxmitpriv->be_txqueue.head = 0;
 971                hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
 972                hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
 973        } else if (pxmitpriv->hwxmit_entry == 4) {
 974                pxmitpriv->vo_txqueue.head = 0;
 975                hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
 976                hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
 977                pxmitpriv->vi_txqueue.head = 0;
 978                hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
 979                hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
 980                pxmitpriv->be_txqueue.head = 0;
 981                hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
 982                hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
 983                pxmitpriv->bk_txqueue.head = 0;
 984                hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
 985                hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
 986        }
 987}
 988
 989static void free_hwxmits(struct _adapter *padapter)
 990{
 991        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
 992
 993        kfree(pxmitpriv->hwxmits);
 994}
 995
 996static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
 997{
 998        sint i;
 999
1000        for (i = 0; i < entry; i++, phwxmit++) {
1001                spin_lock_init(&phwxmit->xmit_lock);
1002                INIT_LIST_HEAD(&phwxmit->pending);
1003                phwxmit->txcmdcnt = 0;
1004                phwxmit->accnt = 0;
1005        }
1006}
1007
1008void xmitframe_xmitbuf_attach(struct xmit_frame *pxmitframe,
1009                        struct xmit_buf *pxmitbuf)
1010{
1011        /* pxmitbuf attach to pxmitframe */
1012        pxmitframe->pxmitbuf = pxmitbuf;
1013        /* urb and irp connection */
1014        pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
1015        /* buffer addr assoc */
1016        pxmitframe->buf_addr = pxmitbuf->pbuf;
1017        /* pxmitframe attach to pxmitbuf */
1018        pxmitbuf->priv_data = pxmitframe;
1019}
1020
1021/*
1022 * tx_action == 0 == no frames to transmit
1023 * tx_action > 0 ==> we have frames to transmit
1024 * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
1025 *                                               to transmit 1 frame.
1026 */
1027
1028int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
1029{
1030        unsigned long irqL;
1031        int ret;
1032        struct xmit_buf *pxmitbuf = NULL;
1033        struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1034        struct pkt_attrib *pattrib = &pxmitframe->attrib;
1035
1036        r8712_do_queue_select(padapter, pattrib);
1037        spin_lock_irqsave(&pxmitpriv->lock, irqL);
1038        if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
1039                ret = false;
1040                r8712_xmit_enqueue(padapter, pxmitframe);
1041                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1042                return ret;
1043        }
1044        pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
1045        if (pxmitbuf == NULL) { /*enqueue packet*/
1046                ret = false;
1047                r8712_xmit_enqueue(padapter, pxmitframe);
1048                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1049        } else { /*dump packet directly*/
1050                spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
1051                ret = true;
1052                xmitframe_xmitbuf_attach(pxmitframe, pxmitbuf);
1053                r8712_xmit_direct(padapter, pxmitframe);
1054        }
1055        return ret;
1056}
1057