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