]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/staging/rtl8188eu/hal/rtl8188eu_xmit.c
Merge branch 'kconfig' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild
[karo-tx-linux.git] / drivers / staging / rtl8188eu / hal / rtl8188eu_xmit.c
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
28 s32     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
38 void    rtl8188eu_free_xmit_priv(struct adapter *adapt)
39 {
40 }
41
42 static 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
51 static 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. */
69 void 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
106 static 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
132 static 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
163 static 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
179 static 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 controled 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 */
354 static 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
419 static 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
437 s32 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         unsigned long irql;
449         struct list_head *xmitframe_plist = NULL, *xmitframe_phead = NULL;
450
451         u32 pbuf;       /*  next pkt address */
452         u32 pbuf_tail;  /*  last pkt tail */
453         u32 len;        /*  packet length, except TXDESC_SIZE and PKT_OFFSET */
454
455         u32 bulksize = haldata->UsbBulkOutSize;
456         u8 desc_cnt;
457         u32 bulkptr;
458
459         /*  dump frame variable */
460         u32 ff_hwaddr;
461
462         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
463
464         /*  check xmitbuffer is ok */
465         if (pxmitbuf == NULL) {
466                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
467                 if (pxmitbuf == NULL)
468                         return false;
469         }
470
471         /* 3 1. pick up first frame */
472         do {
473                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
474
475                 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
476                 if (pxmitframe == NULL) {
477                         /*  no more xmit frame, release xmit buffer */
478                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
479                         return false;
480                 }
481
482                 pxmitframe->pxmitbuf = pxmitbuf;
483                 pxmitframe->buf_addr = pxmitbuf->pbuf;
484                 pxmitbuf->priv_data = pxmitframe;
485
486                 pxmitframe->agg_num = 1; /*  alloc xmitframe should assign to 1. */
487                 pxmitframe->pkt_offset = 1; /*  first frame of aggregation, reserve offset */
488
489                 rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
490
491                 /*  always return ndis_packet after rtw_xmitframe_coalesce */
492                 rtw_os_xmit_complete(adapt, pxmitframe);
493
494                 break;
495         } while (1);
496
497         /* 3 2. aggregate same priority and same DA(AP or STA) frames */
498         pfirstframe = pxmitframe;
499         len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE + (pfirstframe->pkt_offset*PACKET_OFFSET_SZ);
500         pbuf_tail = len;
501         pbuf = _RND8(pbuf_tail);
502
503         /*  check pkt amount in one bulk */
504         desc_cnt = 0;
505         bulkptr = bulksize;
506         if (pbuf < bulkptr) {
507                 desc_cnt++;
508         } else {
509                 desc_cnt = 0;
510                 bulkptr = ((pbuf / bulksize) + 1) * bulksize; /*  round to next bulksize */
511         }
512
513         /*  dequeue same priority packet from station tx queue */
514         psta = pfirstframe->attrib.psta;
515         switch (pfirstframe->attrib.priority) {
516         case 1:
517         case 2:
518                 ptxservq = &(psta->sta_xmitpriv.bk_q);
519                 phwxmit = pxmitpriv->hwxmits + 3;
520                 break;
521         case 4:
522         case 5:
523                 ptxservq = &(psta->sta_xmitpriv.vi_q);
524                 phwxmit = pxmitpriv->hwxmits + 1;
525                 break;
526         case 6:
527         case 7:
528                 ptxservq = &(psta->sta_xmitpriv.vo_q);
529                 phwxmit = pxmitpriv->hwxmits;
530                 break;
531         case 0:
532         case 3:
533         default:
534                 ptxservq = &(psta->sta_xmitpriv.be_q);
535                 phwxmit = pxmitpriv->hwxmits + 2;
536                 break;
537         }
538         _enter_critical_bh(&pxmitpriv->lock, &irql);
539
540         xmitframe_phead = get_list_head(&ptxservq->sta_pending);
541         xmitframe_plist = get_next(xmitframe_phead);
542
543         while (!rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist)) {
544                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
545                 xmitframe_plist = get_next(xmitframe_plist);
546
547                 pxmitframe->agg_num = 0; /*  not first frame of aggregation */
548                 pxmitframe->pkt_offset = 0; /*  not first frame of aggregation, no need to reserve offset */
549
550                 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + (pxmitframe->pkt_offset*PACKET_OFFSET_SZ);
551
552                 if (_RND8(pbuf + len) > MAX_XMITBUF_SZ) {
553                         pxmitframe->agg_num = 1;
554                         pxmitframe->pkt_offset = 1;
555                         break;
556                 }
557                 rtw_list_delete(&pxmitframe->list);
558                 ptxservq->qcnt--;
559                 phwxmit->accnt--;
560
561                 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
562
563                 rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
564                 /*  always return ndis_packet after rtw_xmitframe_coalesce */
565                 rtw_os_xmit_complete(adapt, pxmitframe);
566
567                 /*  (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz */
568                 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, true);
569
570                 /*  don't need xmitframe any more */
571                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
572
573                 /*  handle pointer and stop condition */
574                 pbuf_tail = pbuf + len;
575                 pbuf = _RND8(pbuf_tail);
576
577                 pfirstframe->agg_num++;
578                 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
579                         break;
580
581                 if (pbuf < bulkptr) {
582                         desc_cnt++;
583                         if (desc_cnt == haldata->UsbTxAggDescNum)
584                                 break;
585                 } else {
586                         desc_cnt = 0;
587                         bulkptr = ((pbuf / bulksize) + 1) * bulksize;
588                 }
589         } /* end while (aggregate same priority and same DA(AP or STA) frames) */
590
591         if (_rtw_queue_empty(&ptxservq->sta_pending) == true)
592                 rtw_list_delete(&ptxservq->tx_pending);
593
594         _exit_critical_bh(&pxmitpriv->lock, &irql);
595         if ((pfirstframe->attrib.ether_type != 0x0806) &&
596             (pfirstframe->attrib.ether_type != 0x888e) &&
597             (pfirstframe->attrib.ether_type != 0x88b4) &&
598             (pfirstframe->attrib.dhcp_pkt != 1))
599                 rtw_issue_addbareq_cmd(adapt, pfirstframe);
600         /* 3 3. update first frame txdesc */
601         if ((pbuf_tail % bulksize) == 0) {
602                 /*  remove pkt_offset */
603                 pbuf_tail -= PACKET_OFFSET_SZ;
604                 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
605                 pfirstframe->pkt_offset--;
606         }
607
608         update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, true);
609
610         /* 3 4. write xmit buffer to USB FIFO */
611         ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
612         rtw_write_port(adapt, ff_hwaddr, pbuf_tail, (u8 *)pxmitbuf);
613
614         /* 3 5. update statisitc */
615         pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
616         pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
617
618         rtw_count_tx_stats(adapt, pfirstframe, pbuf_tail);
619
620         rtw_free_xmitframe(pxmitpriv, pfirstframe);
621
622         return true;
623 }
624
625 static s32 xmitframe_direct(struct adapter *adapt, struct xmit_frame *pxmitframe)
626 {
627         s32 res = _SUCCESS;
628
629         res = rtw_xmitframe_coalesce(adapt, pxmitframe->pkt, pxmitframe);
630         if (res == _SUCCESS)
631                 rtw_dump_xframe(adapt, pxmitframe);
632         else
633                 DBG_88E("==> %s xmitframe_coalsece failed\n", __func__);
634         return res;
635 }
636
637 /*
638  * Return
639  *      true    dump packet directly
640  *      false   enqueue packet
641  */
642 static s32 pre_xmitframe(struct adapter *adapt, struct xmit_frame *pxmitframe)
643 {
644         unsigned long irql;
645         s32 res;
646         struct xmit_buf *pxmitbuf = NULL;
647         struct xmit_priv *pxmitpriv = &adapt->xmitpriv;
648         struct pkt_attrib *pattrib = &pxmitframe->attrib;
649         struct mlme_priv *pmlmepriv = &adapt->mlmepriv;
650
651         _enter_critical_bh(&pxmitpriv->lock, &irql);
652
653         if (rtw_txframes_sta_ac_pending(adapt, pattrib) > 0)
654                 goto enqueue;
655
656         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == true)
657                 goto enqueue;
658
659         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
660         if (pxmitbuf == NULL)
661                 goto enqueue;
662
663         _exit_critical_bh(&pxmitpriv->lock, &irql);
664
665         pxmitframe->pxmitbuf = pxmitbuf;
666         pxmitframe->buf_addr = pxmitbuf->pbuf;
667         pxmitbuf->priv_data = pxmitframe;
668
669         if (xmitframe_direct(adapt, pxmitframe) != _SUCCESS) {
670                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
671                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
672         }
673
674         return true;
675
676 enqueue:
677         res = rtw_xmitframe_enqueue(adapt, pxmitframe);
678         _exit_critical_bh(&pxmitpriv->lock, &irql);
679
680         if (res != _SUCCESS) {
681                 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
682                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
683
684                 /*  Trick, make the statistics correct */
685                 pxmitpriv->tx_pkts--;
686                 pxmitpriv->tx_drop++;
687                 return true;
688         }
689
690         return false;
691 }
692
693 s32 rtl8188eu_mgnt_xmit(struct adapter *adapt, struct xmit_frame *pmgntframe)
694 {
695         return rtw_dump_xframe(adapt, pmgntframe);
696 }
697
698 /*
699  * Return
700  *      true    dump packet directly ok
701  *      false   temporary can't transmit packets to hardware
702  */
703 s32 rtl8188eu_hal_xmit(struct adapter *adapt, struct xmit_frame *pxmitframe)
704 {
705         return pre_xmitframe(adapt, pxmitframe);
706 }