linux/drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  12 * more details.
  13 *
  14 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 *
  19 ******************************************************************************/
  20#define _RTL8188E_XMIT_C_
  21#include <osdep_service.h>
  22#include <drv_types.h>
  23#include <wifi.h>
  24#include <osdep_intf.h>
  25#include <usb_ops.h>
  26#include <rtl8188e_hal.h>
  27
  28s32     rtl8188eu_init_xmit_priv(struct adapter *adapt)
  29{
  30        struct xmit_priv        *pxmitpriv = &adapt->xmitpriv;
  31
  32        tasklet_init(&pxmitpriv->xmit_tasklet,
  33                     (void(*)(unsigned long))rtl8188eu_xmit_tasklet,
  34                     (unsigned long)adapt);
  35        return _SUCCESS;
  36}
  37
  38void    rtl8188eu_free_xmit_priv(struct adapter *adapt)
  39{
  40}
  41
  42static u8 urb_zero_packet_chk(struct adapter *adapt, int sz)
  43{
  44        u8 set_tx_desc_offset;
  45        struct hal_data_8188e   *haldata = GET_HAL_DATA(adapt);
  46        set_tx_desc_offset = (((sz + TXDESC_SIZE) %  haldata->UsbBulkOutSize) == 0) ? 1 : 0;
  47
  48        return set_tx_desc_offset;
  49}
  50
  51static void rtl8188eu_cal_txdesc_chksum(struct tx_desc  *ptxdesc)
  52{
  53        u16     *usptr = (u16 *)ptxdesc;
  54        u32 count = 16;         /*  (32 bytes / 2 bytes per XOR) => 16 times */
  55        u32 index;
  56        u16 checksum = 0;
  57
  58        /* Clear first */
  59        ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
  60
  61        for (index = 0; index < count; index++)
  62                checksum = checksum ^ le16_to_cpu(*(__le16 *)(usptr + index));
  63        ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff & checksum);
  64}
  65
  66/*  Description: In normal chip, we should send some packet to Hw which will be used by Fw */
  67/*                      in FW LPS mode. The function is to fill the Tx descriptor of this packets, then */
  68/*                      Fw can tell Hw to send these packet derectly. */
  69void rtl8188e_fill_fake_txdesc(struct adapter *adapt, u8 *desc, u32 BufferLen, u8  ispspoll, u8  is_btqosnull)
  70{
  71        struct tx_desc *ptxdesc;
  72
  73        /*  Clear all status */
  74        ptxdesc = (struct tx_desc *)desc;
  75        _rtw_memset(desc, 0, TXDESC_SIZE);
  76
  77        /* offset 0 */
  78        ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG); /* own, bFirstSeg, bLastSeg; */
  79
  80        ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); /* 32 bytes for TX Desc */
  81
  82        ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); /*  Buffer size + command header */
  83
  84        /* offset 4 */
  85        ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); /*  Fixed queue of Mgnt queue */
  86
  87        /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
  88        if (ispspoll) {
  89                ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
  90        } else {
  91                ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); /*  Hw set sequence number */
  92                ptxdesc->txdw3 |= cpu_to_le32((8 << 28)); /* set bit3 to 1. Suugested by TimChen. 2009.12.29. */
  93        }
  94
  95        if (is_btqosnull)
  96                ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); /*  BT NULL */
  97
  98        /* offset 16 */
  99        ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
 100
 101        /*  USB interface drop packet if the checksum of descriptor isn't correct. */
 102        /*  Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
 103        rtl8188eu_cal_txdesc_chksum(ptxdesc);
 104}
 105
 106static void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
 107{
 108        if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
 109                switch (pattrib->encrypt) {
 110                /* SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES */
 111                case _WEP40_:
 112                case _WEP104_:
 113                        ptxdesc->txdw1 |= cpu_to_le32((0x01<<SEC_TYPE_SHT)&0x00c00000);
 114                        ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
 115                        break;
 116                case _TKIP_:
 117                case _TKIP_WTMIC_:
 118                        ptxdesc->txdw1 |= cpu_to_le32((0x01<<SEC_TYPE_SHT)&0x00c00000);
 119                        ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
 120                        break;
 121                case _AES_:
 122                        ptxdesc->txdw1 |= cpu_to_le32((0x03<<SEC_TYPE_SHT)&0x00c00000);
 123                        ptxdesc->txdw2 |= cpu_to_le32(0x7 << AMPDU_DENSITY_SHT);
 124                        break;
 125                case _NO_PRIVACY_:
 126                default:
 127                        break;
 128                }
 129        }
 130}
 131
 132static void fill_txdesc_vcs(struct pkt_attrib *pattrib, __le32 *pdw)
 133{
 134        switch (pattrib->vcs_mode) {
 135        case RTS_CTS:
 136                *pdw |= cpu_to_le32(RTS_EN);
 137                break;
 138        case CTS_TO_SELF:
 139                *pdw |= cpu_to_le32(CTS_2_SELF);
 140                break;
 141        case NONE_VCS:
 142        default:
 143                break;
 144        }
 145        if (pattrib->vcs_mode) {
 146                *pdw |= cpu_to_le32(HW_RTS_EN);
 147                /*  Set RTS BW */
 148                if (pattrib->ht_en) {
 149                        *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(27)) : 0;
 150
 151                        if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
 152                                *pdw |= cpu_to_le32((0x01 << 28) & 0x30000000);
 153                        else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
 154                                *pdw |= cpu_to_le32((0x02 << 28) & 0x30000000);
 155                        else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
 156                                *pdw |= 0;
 157                        else
 158                                *pdw |= cpu_to_le32((0x03 << 28) & 0x30000000);
 159                }
 160        }
 161}
 162
 163static void fill_txdesc_phy(struct pkt_attrib *pattrib, __le32 *pdw)
 164{
 165        if (pattrib->ht_en) {
 166                *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40) ? cpu_to_le32(BIT(25)) : 0;
 167
 168                if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
 169                        *pdw |= cpu_to_le32((0x01 << DATA_SC_SHT) & 0x003f0000);
 170                else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
 171                        *pdw |= cpu_to_le32((0x02 << DATA_SC_SHT) & 0x003f0000);
 172                else if (pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
 173                        *pdw |= 0;
 174                else
 175                        *pdw |= cpu_to_le32((0x03 << DATA_SC_SHT) & 0x003f0000);
 176        }
 177}
 178
 179static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
 180{
 181        int     pull = 0;
 182        uint    qsel;
 183        u8 data_rate, pwr_status, offset;
 184        struct adapter          *adapt = pxmitframe->padapter;
 185        struct pkt_attrib       *pattrib = &pxmitframe->attrib;
 186        struct hal_data_8188e   *haldata = GET_HAL_DATA(adapt);
 187        struct tx_desc  *ptxdesc = (struct tx_desc *)pmem;
 188        struct mlme_ext_priv    *pmlmeext = &adapt->mlmeextpriv;
 189        struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
 190        int     bmcst = IS_MCAST(pattrib->ra);
 191
 192        if (adapt->registrypriv.mp_mode == 0) {
 193                if ((!bagg_pkt) && (urb_zero_packet_chk(adapt, sz) == 0)) {
 194                        ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
 195                        pull = 1;
 196                }
 197        }
 198
 199        _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
 200
 201        /* 4 offset 0 */
 202        ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
 203        ptxdesc->txdw0 |= cpu_to_le32(sz & 0x0000ffff);/* update TXPKTSIZE */
 204
 205        offset = TXDESC_SIZE + OFFSET_SZ;
 206
 207        ptxdesc->txdw0 |= cpu_to_le32(((offset) << OFFSET_SHT) & 0x00ff0000);/* 32 bytes for TX Desc */
 208
 209        if (bmcst)
 210                ptxdesc->txdw0 |= cpu_to_le32(BMC);
 211
 212        if (adapt->registrypriv.mp_mode == 0) {
 213                if (!bagg_pkt) {
 214                        if ((pull) && (pxmitframe->pkt_offset > 0))
 215                                pxmitframe->pkt_offset = pxmitframe->pkt_offset - 1;
 216                }
 217        }
 218
 219        /*  pkt_offset, unit:8 bytes padding */
 220        if (pxmitframe->pkt_offset > 0)
 221                ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
 222
 223        /* driver uses rate */
 224        ptxdesc->txdw4 |= cpu_to_le32(USERATE);/* rate control always by driver */
 225
 226        if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
 227                /* offset 4 */
 228                ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3F);
 229
 230                qsel = (uint)(pattrib->qsel & 0x0000001f);
 231                ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
 232
 233                ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000F0000);
 234
 235                fill_txdesc_sectype(pattrib, ptxdesc);
 236
 237                if (pattrib->ampdu_en) {
 238                        ptxdesc->txdw2 |= cpu_to_le32(AGG_EN);/* AGG EN */
 239                        ptxdesc->txdw6 = cpu_to_le32(0x6666f800);
 240                } else {
 241                        ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
 242                }
 243
 244                /* offset 8 */
 245
 246                /* offset 12 */
 247                ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum << SEQ_SHT) & 0x0FFF0000);
 248
 249                /* offset 16 , offset 20 */
 250                if (pattrib->qos_en)
 251                        ptxdesc->txdw4 |= cpu_to_le32(QOS);/* QoS */
 252
 253                /* offset 20 */
 254                if (pxmitframe->agg_num > 1)
 255                        ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << USB_TXAGG_NUM_SHT) & 0xFF000000);
 256
 257                if ((pattrib->ether_type != 0x888e) &&
 258                    (pattrib->ether_type != 0x0806) &&
 259                    (pattrib->ether_type != 0x88b4) &&
 260                    (pattrib->dhcp_pkt != 1)) {
 261                        /* Non EAP & ARP & DHCP type data packet */
 262
 263                        fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
 264                        fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
 265
 266                        ptxdesc->txdw4 |= cpu_to_le32(0x00000008);/* RTS Rate=24M */
 267                        ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);/* DATA/RTS  Rate FB LMT */
 268
 269                        if (pattrib->ht_en) {
 270                                if (ODM_RA_GetShortGI_8188E(&haldata->odmpriv, pattrib->mac_id))
 271                                        ptxdesc->txdw5 |= cpu_to_le32(SGI);/* SGI */
 272                        }
 273                        data_rate = ODM_RA_GetDecisionRate_8188E(&haldata->odmpriv, pattrib->mac_id);
 274                        ptxdesc->txdw5 |= cpu_to_le32(data_rate & 0x3F);
 275                        pwr_status = ODM_RA_GetHwPwrStatus_8188E(&haldata->odmpriv, pattrib->mac_id);
 276                        ptxdesc->txdw4 |= cpu_to_le32((pwr_status & 0x7) << PWR_STATUS_SHT);
 277                } else {
 278                        /*  EAP data packet and ARP packet and DHCP. */
 279                        /*  Use the 1M data rate to send the EAP/ARP packet. */
 280                        /*  This will maybe make the handshake smooth. */
 281                        ptxdesc->txdw2 |= cpu_to_le32(AGG_BK);/* AGG BK */
 282                        if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
 283                                ptxdesc->txdw4 |= cpu_to_le32(BIT(24));/*  DATA_SHORT */
 284                        ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
 285                }
 286        } else if ((pxmitframe->frame_tag&0x0f) == MGNT_FRAMETAG) {
 287                /* offset 4 */
 288                ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id & 0x3f);
 289
 290                qsel = (uint)(pattrib->qsel&0x0000001f);
 291                ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
 292
 293                ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid << RATE_ID_SHT) & 0x000f0000);
 294
 295                /* offset 8 */
 296                /* CCX-TXRPT ack for xmit mgmt frames. */
 297                if (pxmitframe->ack_report)
 298                        ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
 299
 300                /* offset 12 */
 301                ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<SEQ_SHT)&0x0FFF0000);
 302
 303                /* offset 20 */
 304                ptxdesc->txdw5 |= cpu_to_le32(RTY_LMT_EN);/* retry limit enable */
 305                if (pattrib->retry_ctrl)
 306                        ptxdesc->txdw5 |= cpu_to_le32(0x00180000);/* retry limit = 6 */
 307                else
 308                        ptxdesc->txdw5 |= cpu_to_le32(0x00300000);/* retry limit = 12 */
 309
 310                ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
 311        } else if ((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG) {
 312                DBG_88E("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
 313        } else if (((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) &&
 314                   (adapt->registrypriv.mp_mode == 1)) {
 315                fill_txdesc_for_mp(adapt, ptxdesc);
 316        } else {
 317                DBG_88E("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
 318
 319                /* offset 4 */
 320                ptxdesc->txdw1 |= cpu_to_le32((4) & 0x3f);/* CAM_ID(MAC_ID) */
 321
 322                ptxdesc->txdw1 |= cpu_to_le32((6 << RATE_ID_SHT) & 0x000f0000);/* raid */
 323
 324                /* offset 8 */
 325
 326                /* offset 12 */
 327                ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<SEQ_SHT)&0x0fff0000);
 328
 329                /* offset 20 */
 330                ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
 331        }
 332
 333        /*  2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
 334        /*  (1) The sequence number of each non-Qos frame / broadcast / multicast / */
 335        /*  mgnt frame should be controlled by Hw because Fw will also send null data */
 336        /*  which we cannot control when Fw LPS enable. */
 337        /*  --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
 338        /*  (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
 339        /*  (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
 340        /*  2010.06.23. Added by tynli. */
 341        if (!pattrib->qos_en) {
 342                ptxdesc->txdw3 |= cpu_to_le32(EN_HWSEQ); /*  Hw set sequence number */
 343                ptxdesc->txdw4 |= cpu_to_le32(HW_SSN);  /*  Hw set sequence number */
 344        }
 345
 346        ODM_SetTxAntByTxInfo_88E(&haldata->odmpriv, pmem, pattrib->mac_id);
 347
 348        rtl8188eu_cal_txdesc_chksum(ptxdesc);
 349        _dbg_dump_tx_info(adapt, pxmitframe->frame_tag, ptxdesc);
 350        return pull;
 351}
 352
 353/* for non-agg data frame or  management frame */
 354static s32 rtw_dump_xframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
 355{
 356        s32 ret = _SUCCESS;
 357        s32 inner_ret = _SUCCESS;
 358        int t, sz, w_sz, pull = 0;
 359        u8 *mem_addr;
 360        u32 ff_hwaddr;
 361        struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
 362        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 363        struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
 364        struct security_priv *psecuritypriv = &adapt->securitypriv;
 365        if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
 366            (pxmitframe->attrib.ether_type != 0x0806) &&
 367            (pxmitframe->attrib.ether_type != 0x888e) &&
 368            (pxmitframe->attrib.ether_type != 0x88b4) &&
 369            (pxmitframe->attrib.dhcp_pkt != 1))
 370                rtw_issue_addbareq_cmd(adapt, pxmitframe);
 371        mem_addr = pxmitframe->buf_addr;
 372
 373        RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_dump_xframe()\n"));
 374
 375        for (t = 0; t < pattrib->nr_frags; t++) {
 376                if (inner_ret != _SUCCESS && ret == _SUCCESS)
 377                        ret = _FAIL;
 378
 379                if (t != (pattrib->nr_frags - 1)) {
 380                        RT_TRACE(_module_rtl871x_xmit_c_, _drv_err_, ("pattrib->nr_frags=%d\n", pattrib->nr_frags));
 381
 382                        sz = pxmitpriv->frag_len;
 383                        sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
 384                } else {
 385                        /* no frag */
 386                        sz = pattrib->last_txcmdsz;
 387                }
 388
 389                pull = update_txdesc(pxmitframe, mem_addr, sz, false);
 390
 391                if (pull) {
 392                        mem_addr += PACKET_OFFSET_SZ; /* pull txdesc head */
 393                        pxmitframe->buf_addr = mem_addr;
 394                        w_sz = sz + TXDESC_SIZE;
 395                } else {
 396                        w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
 397                }
 398                ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
 399
 400                inner_ret = rtw_write_port(adapt, ff_hwaddr, w_sz, (unsigned char *)pxmitbuf);
 401
 402                rtw_count_tx_stats(adapt, pxmitframe, sz);
 403
 404                RT_TRACE(_module_rtl871x_xmit_c_, _drv_info_, ("rtw_write_port, w_sz=%d\n", w_sz));
 405
 406                mem_addr += w_sz;
 407
 408                mem_addr = (u8 *)RND4(((size_t)(mem_addr)));
 409        }
 410
 411        rtw_free_xmitframe(pxmitpriv, pxmitframe);
 412
 413        if  (ret != _SUCCESS)
 414                rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
 415
 416        return ret;
 417}
 418
 419static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
 420{
 421        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 422
 423        u32 len = 0;
 424
 425        /*  no consider fragement */
 426        len = pattrib->hdrlen + pattrib->iv_len +
 427                SNAP_SIZE + sizeof(u16) +
 428                pattrib->pktlen +
 429                ((pattrib->bswenc) ? pattrib->icv_len : 0);
 430
 431        if (pattrib->encrypt == _TKIP_)
 432                len += 8;
 433
 434        return len;
 435}
 436
 437s32 rtl8188eu_xmitframe_complete(struct adapter *adapt, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
 438{
 439        struct hal_data_8188e   *haldata = GET_HAL_DATA(adapt);
 440        struct xmit_frame *pxmitframe = NULL;
 441        struct xmit_frame *pfirstframe = NULL;
 442
 443        /*  aggregate variable */
 444        struct hw_xmit *phwxmit;
 445        struct sta_info *psta = NULL;
 446        struct tx_servq *ptxservq = NULL;
 447
 448        struct list_head *xmitframe_plist = NULL, *xmitframe_phead = NULL;
 449
 450        u32 pbuf;       /*  next pkt address */
 451        u32 pbuf_tail;  /*  last pkt tail */
 452        u32 len;        /*  packet length, except TXDESC_SIZE and PKT_OFFSET */
 453
 454        u32 bulksize = haldata->UsbBulkOutSize;
 455        u8 desc_cnt;
 456        u32 bulkptr;
 457
 458        /*  dump frame variable */
 459        u32 ff_hwaddr;
 460
 461        RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
 462
 463        /*  check xmitbuffer is ok */
 464        if (pxmitbuf == NULL) {
 465                pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
 466                if (pxmitbuf == NULL)
 467                        return false;
 468        }
 469
 470        /* 3 1. pick up first frame */
 471        do {
 472                rtw_free_xmitframe(pxmitpriv, pxmitframe);
 473
 474                pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
 475                if (pxmitframe == NULL) {
 476                        /*  no more xmit frame, release xmit buffer */
 477                        rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
 478                        return false;
 479                }
 480
 481                pxmitframe->pxmitbuf = pxmitbuf;
 482                pxmitframe->buf_addr = pxmitbuf->pbuf;
 483                pxmitbuf->priv_data = pxmitframe;
 484
 485                pxmitframe->agg_num = 1; /*  alloc xmitframe should assign to 1. */
 486                pxmitframe->pkt_offset = 1; /*  first frame of aggregation, reserve offset */
 487
 488                rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
 489
 490                /*  always return ndis_packet after rtw_xmitframe_coalesce */
 491                rtw_os_xmit_complete(adapt, pxmitframe);
 492
 493                break;
 494        } while (1);
 495
 496        /* 3 2. aggregate same priority and same DA(AP or STA) frames */
 497        pfirstframe = pxmitframe;
 498        len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset*PACKET_OFFSET_SZ);
 499        pbuf_tail = len;
 500        pbuf = _RND8(pbuf_tail);
 501
 502        /*  check pkt amount in one bulk */
 503        desc_cnt = 0;
 504        bulkptr = bulksize;
 505        if (pbuf < bulkptr) {
 506                desc_cnt++;
 507        } else {
 508                desc_cnt = 0;
 509                bulkptr = ((pbuf / bulksize) + 1) * bulksize; /*  round to next bulksize */
 510        }
 511
 512        /*  dequeue same priority packet from station tx queue */
 513        psta = pfirstframe->attrib.psta;
 514        switch (pfirstframe->attrib.priority) {
 515        case 1:
 516        case 2:
 517                ptxservq = &(psta->sta_xmitpriv.bk_q);
 518                phwxmit = pxmitpriv->hwxmits + 3;
 519                break;
 520        case 4:
 521        case 5:
 522                ptxservq = &(psta->sta_xmitpriv.vi_q);
 523                phwxmit = pxmitpriv->hwxmits + 1;
 524                break;
 525        case 6:
 526        case 7:
 527                ptxservq = &(psta->sta_xmitpriv.vo_q);
 528                phwxmit = pxmitpriv->hwxmits;
 529                break;
 530        case 0:
 531        case 3:
 532        default:
 533                ptxservq = &(psta->sta_xmitpriv.be_q);
 534                phwxmit = pxmitpriv->hwxmits + 2;
 535                break;
 536        }
 537        spin_lock_bh(&pxmitpriv->lock);
 538
 539        xmitframe_phead = get_list_head(&ptxservq->sta_pending);
 540        xmitframe_plist = get_next(xmitframe_phead);
 541
 542        while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
 543                pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
 544                xmitframe_plist = get_next(xmitframe_plist);
 545
 546                pxmitframe->agg_num = 0; /*  not first frame of aggregation */
 547                pxmitframe->pkt_offset = 0; /*  not first frame of aggregation, no need to reserve offset */
 548
 549                len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset*PACKET_OFFSET_SZ);
 550
 551                if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) {
 552                        pxmitframe->agg_num = 1;
 553                        pxmitframe->pkt_offset = 1;
 554                        break;
 555                }
 556                rtw_list_delete(&pxmitframe->list);
 557                ptxservq->qcnt--;
 558                phwxmit->accnt--;
 559
 560                pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
 561
 562                rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
 563                /*  always return ndis_packet after rtw_xmitframe_coalesce */
 564                rtw_os_xmit_complete(adapt, pxmitframe);
 565
 566                /*  (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
 567                update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, true);
 568
 569                /*  don't need xmitframe any more */
 570                rtw_free_xmitframe(pxmitpriv, pxmitframe);
 571
 572                /*  handle pointer and stop condition */
 573                pbuf_tail = pbuf + len;
 574                pbuf = _RND8(pbuf_tail);
 575
 576                pfirstframe->agg_num++;
 577                if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
 578                        break;
 579
 580                if (pbuf < bulkptr) {
 581                        desc_cnt++;
 582                        if (desc_cnt == haldata->UsbTxAggDescNum)
 583                                break;
 584                } else {
 585                        desc_cnt = 0;
 586                        bulkptr = ((pbuf / bulksize) + 1) * bulksize;
 587                }
 588        } /* end while (aggregate same priority and same DA(AP or STA) frames) */
 589
 590        if (_rtw_queue_empty(&ptxservq->sta_pending) == true)
 591                rtw_list_delete(&ptxservq->tx_pending);
 592
 593        spin_unlock_bh(&pxmitpriv->lock);
 594        if ((pfirstframe->attrib.ether_type != 0x0806) &&
 595            (pfirstframe->attrib.ether_type != 0x888e) &&
 596            (pfirstframe->attrib.ether_type != 0x88b4) &&
 597            (pfirstframe->attrib.dhcp_pkt != 1))
 598                rtw_issue_addbareq_cmd(adapt, pfirstframe);
 599        /* 3 3. update first frame txdesc */
 600        if ((pbuf_tail % bulksize) == 0) {
 601                /*  remove pkt_offset */
 602                pbuf_tail -= PACKET_OFFSET_SZ;
 603                pfirstframe->buf_addr += PACKET_OFFSET_SZ;
 604                pfirstframe->pkt_offset--;
 605        }
 606
 607        update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, true);
 608
 609        /* 3 4. write xmit buffer to USB FIFO */
 610        ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
 611        rtw_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
 612
 613        /* 3 5. update statisitc */
 614        pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
 615        pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
 616
 617        rtw_count_tx_stats(adapt, pfirstframe, pbuf_tail);
 618
 619        rtw_free_xmitframe(pxmitpriv, pfirstframe);
 620
 621        return true;
 622}
 623
 624static s32 xmitframe_direct(struct adapter *adapt, struct xmit_frame *pxmitframe)
 625{
 626        s32 res = _SUCCESS;
 627
 628        res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
 629        if (res == _SUCCESS)
 630                rtw_dump_xframe(adapt, pxmitframe);
 631        else
 632                DBG_88E("==> %s xmitframe_coalsece failed\n", __func__);
 633        return res;
 634}
 635
 636/*
 637 * Return
 638 *      true    dump packet directly
 639 *      false   enqueue packet
 640 */
 641static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
 642{
 643        s32 res;
 644        struct xmit_buf *pxmitbuf = NULL;
 645        struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
 646        struct pkt_attrib *pattrib = &pxmitframe->attrib;
 647        struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
 648
 649        spin_lock_bh(&pxmitpriv->lock);
 650
 651        if (rtw_txframes_sta_ac_pending(adapt, pattrib) > 0)
 652                goto enqueue;
 653
 654        if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
 655                goto enqueue;
 656
 657        pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
 658        if (pxmitbuf == NULL)
 659                goto enqueue;
 660
 661        spin_unlock_bh(&pxmitpriv->lock);
 662
 663        pxmitframe->pxmitbuf = pxmitbuf;
 664        pxmitframe->buf_addr = pxmitbuf->pbuf;
 665        pxmitbuf->priv_data = pxmitframe;
 666
 667        if (xmitframe_direct(adapt, pxmitframe) != _SUCCESS) {
 668                rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
 669                rtw_free_xmitframe(pxmitpriv, pxmitframe);
 670        }
 671
 672        return true;
 673
 674enqueue:
 675        res = rtw_xmitframe_enqueue(adapt, pxmitframe);
 676        spin_unlock_bh(&pxmitpriv->lock);
 677
 678        if (res != _SUCCESS) {
 679                RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
 680                rtw_free_xmitframe(pxmitpriv, pxmitframe);
 681
 682                /*  Trick, make the statistics correct */
 683                pxmitpriv->tx_pkts--;
 684                pxmitpriv->tx_drop++;
 685                return true;
 686        }
 687
 688        return false;
 689}
 690
 691s32 rtl8188eu_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe)
 692{
 693        return rtw_dump_xframe(adapt, pmgntframe);
 694}
 695
 696/*
 697 * Return
 698 *      true    dump packet directly ok
 699 *      false   temporary can't transmit packets to hardware
 700 */
 701s32 rtl8188eu_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
 702{
 703        return pre_xmitframe(adapt, pxmitframe);
 704}
 705