Merge branch 'develop-3.10' of ssh://10.10.10.29/rk/kernel into xxh_develop
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723bu / hal / rtl8723b / usb / rtl8723bu_xmit.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *                                        
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20  
21  #define _RTL8723BU_XMIT_C_
22
23 #include <rtl8723b_hal.h>
24
25
26 s32     rtl8723bu_init_xmit_priv(_adapter *padapter)
27 {
28         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
29
30 #ifdef PLATFORM_LINUX
31         tasklet_init(&pxmitpriv->xmit_tasklet,
32              (void(*)(unsigned long))rtl8723bu_xmit_tasklet,
33              (unsigned long)padapter);
34 #endif
35         return _SUCCESS;
36 }
37
38 void    rtl8723bu_free_xmit_priv(_adapter *padapter)
39 {
40 }
41
42 void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc)
43 {
44         u8 bDumpTxPkt;
45         u8 bDumpTxDesc = _FALSE;
46         rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(bDumpTxPkt));
47
48         if(bDumpTxPkt ==1){//dump txdesc for data frame
49                 DBG_871X("dump tx_desc for data frame\n");
50                 if((frame_tag&0x0f) == DATA_FRAMETAG){  
51                         bDumpTxDesc = _TRUE;            
52                 }
53         }       
54         else if(bDumpTxPkt ==2){//dump txdesc for mgnt frame
55                 DBG_871X("dump tx_desc for mgnt frame\n");
56                 if((frame_tag&0x0f) == MGNT_FRAMETAG){  
57                         bDumpTxDesc = _TRUE;            
58                 }
59         }       
60         else if(bDumpTxPkt ==3){//dump early info
61         }
62
63         if(bDumpTxDesc){
64                 //      ptxdesc->txdw4 = cpu_to_le32(0x00001006);//RTS Rate=24M
65                 //      ptxdesc->txdw6 = 0x6666f800;
66                 DBG_8192C("=====================================\n");
67                 DBG_8192C("txdw0(0x%08x)\n",ptxdesc->txdw0);
68                 DBG_8192C("txdw1(0x%08x)\n",ptxdesc->txdw1);
69                 DBG_8192C("txdw2(0x%08x)\n",ptxdesc->txdw2);
70                 DBG_8192C("txdw3(0x%08x)\n",ptxdesc->txdw3);
71                 DBG_8192C("txdw4(0x%08x)\n",ptxdesc->txdw4);
72                 DBG_8192C("txdw5(0x%08x)\n",ptxdesc->txdw5);
73                 DBG_8192C("txdw6(0x%08x)\n",ptxdesc->txdw6);
74                 DBG_8192C("txdw7(0x%08x)\n",ptxdesc->txdw7);
75                 DBG_8192C("=====================================\n");
76         }
77
78 }
79
80 int urb_zero_packet_chk(_adapter *padapter, int sz)
81 {
82         u8 blnSetTxDescOffset;
83         HAL_DATA_TYPE   *pHalData       = GET_HAL_DATA(padapter);
84         blnSetTxDescOffset = (((sz + TXDESC_SIZE) %  pHalData->UsbBulkOutSize) ==0)?1:0;
85
86         return blnSetTxDescOffset;
87 }
88 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
89 {
90         if ((pattrib->encrypt > 0) && !pattrib->bswenc)
91         {
92                 switch (pattrib->encrypt)
93                 {       
94                         //SEC_TYPE
95                         case _WEP40_:
96                         case _WEP104_:
97                                         ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
98                                         break;                          
99                         case _TKIP_:
100                         case _TKIP_WTMIC_:      
101                                         //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
102                                         ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
103                                         break;
104                         case _AES_:
105                                         ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
106                                         break;
107                         case _NO_PRIVACY_:
108                         default:
109                                         break;
110                 
111                 }
112                 
113         }
114
115 }
116
117 void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
118 {
119         //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);        
120
121         switch(pattrib->vcs_mode)
122         {
123                 case RTS_CTS:
124                         *pdw |= cpu_to_le32(BIT(12));
125                         break;
126                 case CTS_TO_SELF:
127                         *pdw |= cpu_to_le32(BIT(11));
128                         break;
129                 case NONE_VCS:
130                 default:
131                         break;          
132         }
133
134         if(pattrib->vcs_mode) {
135                 *pdw |= cpu_to_le32(BIT(13));
136
137                 // Set RTS BW
138                 if(pattrib->ht_en)
139                 {
140                         *pdw |= (pattrib->bwmode&CHANNEL_WIDTH_40)?     cpu_to_le32(BIT(27)):0;
141
142                         if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
143                                 *pdw |= cpu_to_le32((0x01<<28)&0x30000000);
144                         else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
145                                 *pdw |= cpu_to_le32((0x02<<28)&0x30000000);
146                         else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
147                                 *pdw |= 0;
148                         else
149                                 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
150                 }
151         }
152 }
153
154 void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
155 {
156         //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
157
158         if(pattrib->ht_en)
159         {
160                 *pdw |= (pattrib->bwmode&CHANNEL_WIDTH_40)?     cpu_to_le32(BIT(25)):0;
161
162                 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
163                         *pdw |= cpu_to_le32((0x01<<20)&0x003f0000);
164                 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
165                         *pdw |= cpu_to_le32((0x02<<20)&0x003f0000);
166                 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
167                         *pdw |= 0;
168                 else
169                         *pdw |= cpu_to_le32((0x03<<20)&0x003f0000);
170         }
171 }
172
173 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
174 {
175         int     pull=0;
176         
177
178         _adapter                        *padapter = pxmitframe->padapter;
179         struct tx_desc  *ptxdesc = (struct tx_desc *)pmem;
180 #if 0   
181         uint    qsel;
182         struct mlme_priv        *pmlmepriv = &padapter->mlmepriv;               
183         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
184         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
185         struct dm_priv  *pdmpriv = &pHalData->dmpriv;
186
187         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
188         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
189         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
190         sint    bmcst = IS_MCAST(pattrib->ra);
191 #ifdef CONFIG_P2P
192         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
193 #endif //CONFIG_P2P
194 #endif
195 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
196         if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
197         {
198                 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
199                 pull = 1;
200                 pxmitframe->pkt_offset --;
201
202         }
203 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
204
205         _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
206
207         rtl8723b_update_txdesc(pxmitframe, (u8 *)ptxdesc);
208         _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc);
209         return pull;
210                 
211 }
212
213 #ifdef CONFIG_XMIT_THREAD_MODE
214 /*
215  * Description
216  *      Transmit xmitbuf to hardware tx fifo
217  *
218  * Return
219  *      _SUCCESS        ok
220  *      _FAIL           something error
221  */
222 s32 rtl8723bu_xmit_buf_handler(PADAPTER padapter)
223 {
224         //PHAL_DATA_TYPE phal;
225         struct xmit_priv *pxmitpriv;
226         struct xmit_buf *pxmitbuf;
227         s32 ret;
228
229
230         //phal = GET_HAL_DATA(padapter);
231         pxmitpriv = &padapter->xmitpriv;
232
233         ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
234         if (_FAIL == ret) {
235                 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
236                                  ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
237                 return _FAIL;
238         }
239
240         ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
241         if (ret) {
242                 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
243                                  ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
244                                   __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
245                 return _FAIL;
246         }
247
248         if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
249                 return _SUCCESS;
250
251 #ifdef CONFIG_LPS_LCLK
252         ret = rtw_register_tx_alive(padapter);
253         if (ret != _SUCCESS) {
254                 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
255                                  ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
256                 return _SUCCESS;
257         }
258 #endif
259
260         do {
261                 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
262                 if (pxmitbuf == NULL) break;
263
264                 rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);
265
266         } while (1);
267
268 #ifdef CONFIG_LPS_LCLK
269         rtw_unregister_tx_alive(padapter);
270 #endif
271
272         return _SUCCESS;
273 }
274 #endif
275
276
277 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
278 {
279         s32 ret = _SUCCESS;
280         s32 inner_ret = _SUCCESS;
281         int t, sz, w_sz, pull=0;
282         u8 *mem_addr;
283         u32 ff_hwaddr;
284         struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
285         struct pkt_attrib *pattrib = &pxmitframe->attrib;
286         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
287         struct security_priv *psecuritypriv = &padapter->securitypriv;
288
289         if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
290             (pxmitframe->attrib.ether_type != 0x0806) &&
291             (pxmitframe->attrib.ether_type != 0x888e) &&
292             (pxmitframe->attrib.dhcp_pkt != 1))
293         {
294                 rtw_issue_addbareq_cmd(padapter, pxmitframe);
295         }
296         
297         mem_addr = pxmitframe->buf_addr;
298
299        RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
300         
301         for (t = 0; t < pattrib->nr_frags; t++)
302         {
303                 if (inner_ret != _SUCCESS && ret == _SUCCESS)
304                         ret = _FAIL;
305
306                 if (t != (pattrib->nr_frags - 1))
307                 {
308                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
309
310                         sz = pxmitpriv->frag_len;
311                         sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);                                       
312                 }
313                 else //no frag
314                 {
315                         sz = pattrib->last_txcmdsz;
316                 }
317
318                 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
319 //              rtl8723b_update_txdesc(pxmitframe, mem_addr+PACKET_OFFSET_SZ);
320
321                 if(pull)
322                 {
323                         mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
324                         
325                         //pxmitbuf ->pbuf = mem_addr;                   
326                         pxmitframe->buf_addr = mem_addr;
327
328                         w_sz = sz + TXDESC_SIZE;
329                 }
330                 else
331                 {
332                         w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
333                 }       
334
335                 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
336 #ifdef CONFIG_XMIT_THREAD_MODE
337                 pxmitbuf->len = w_sz;
338                 pxmitbuf->ff_hwaddr = ff_hwaddr;
339                 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
340 #else
341                 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
342 #endif
343                 rtw_count_tx_stats(padapter, pxmitframe, sz);
344
345
346                 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
347                 //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);      
348
349                 mem_addr += w_sz;
350
351                 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
352
353         }
354         
355         rtw_free_xmitframe(pxmitpriv, pxmitframe);
356
357         if  (ret != _SUCCESS)
358                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
359
360         return ret;     
361 }
362
363 #ifdef CONFIG_USB_TX_AGGREGATION
364 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
365 {
366         struct pkt_attrib *pattrib = &pxmitframe->attrib;
367
368         u32     len = 0;
369
370         // no consider fragement
371         len = pattrib->hdrlen + pattrib->iv_len +
372                 SNAP_SIZE + sizeof(u16) +
373                 pattrib->pktlen +
374                 ((pattrib->bswenc) ? pattrib->icv_len : 0);
375
376         if(pattrib->encrypt ==_TKIP_)
377                 len += 8;
378
379         return len;
380 }
381
382 #define IDEA_CONDITION 1        // check all packets before enqueue
383 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
384 {
385         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
386         struct xmit_frame *pxmitframe = NULL;
387         struct xmit_frame *pfirstframe = NULL;
388
389         // aggregate variable
390         struct hw_xmit *phwxmit;
391         struct sta_info *psta = NULL;
392         struct tx_servq *ptxservq = NULL;
393
394         _irqL irqL;
395         _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
396
397         u32     pbuf;   // next pkt address
398         u32     pbuf_tail;      // last pkt tail
399         u32     len;    // packet length, except TXDESC_SIZE and PKT_OFFSET
400
401         u32     bulkSize = pHalData->UsbBulkOutSize;
402         u8      descCount;
403         u32     bulkPtr;
404
405         // dump frame variable
406         u32 ff_hwaddr;
407
408 #ifndef IDEA_CONDITION
409         int res = _SUCCESS;
410 #endif
411
412         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
413
414
415         // check xmitbuffer is ok
416         if (pxmitbuf == NULL) {
417                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
418                 if (pxmitbuf == NULL) return _FALSE;
419         }
420
421
422         //3 1. pick up first frame
423         do {
424                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
425                         
426                 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
427                 if (pxmitframe == NULL) {
428                         // no more xmit frame, release xmit buffer
429                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
430                         return _FALSE;
431                 }
432
433
434 #ifndef IDEA_CONDITION
435                 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
436                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
437                                  ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
438                                   pxmitframe->frame_tag, DATA_FRAMETAG));
439 //                      rtw_free_xmitframe(pxmitpriv, pxmitframe);
440                         continue;
441                 }
442
443                 // TID 0~15
444                 if ((pxmitframe->attrib.priority < 0) ||
445                     (pxmitframe->attrib.priority > 15)) {
446                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
447                                  ("xmitframe_complete: TID(%d) should be 0~15!\n",
448                                   pxmitframe->attrib.priority));
449 //                      rtw_free_xmitframe(pxmitpriv, pxmitframe);
450                         continue;
451                 }
452 #endif
453
454                 pxmitframe->pxmitbuf = pxmitbuf;
455                 pxmitframe->buf_addr = pxmitbuf->pbuf;
456                 pxmitbuf->priv_data = pxmitframe;
457
458                 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
459                 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
460
461                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
462                         DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
463                         continue;
464                 }
465
466
467                 // always return ndis_packet after rtw_xmitframe_coalesce
468                 rtw_os_xmit_complete(padapter, pxmitframe);
469
470                 break;
471         } while (1);
472
473         //3 2. aggregate same priority and same DA(AP or STA) frames
474         pfirstframe = pxmitframe;
475         len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
476         pbuf_tail = len;
477         pbuf = _RND8(pbuf_tail);
478
479         // check pkt amount in one bluk
480         descCount = 0;
481         bulkPtr = bulkSize;
482         if (pbuf < bulkPtr)
483                 descCount++;
484         else {
485                 descCount = 0;
486                 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
487         }
488
489         // dequeue same priority packet from station tx queue
490         psta = pfirstframe->attrib.psta;
491         switch (pfirstframe->attrib.priority) {
492                 case 1:
493                 case 2:
494                         ptxservq = &(psta->sta_xmitpriv.bk_q);
495                         phwxmit = pxmitpriv->hwxmits + 3;
496                         break;
497
498                 case 4:
499                 case 5:
500                         ptxservq = &(psta->sta_xmitpriv.vi_q);
501                         phwxmit = pxmitpriv->hwxmits + 1;
502                         break;
503
504                 case 6:
505                 case 7:
506                         ptxservq = &(psta->sta_xmitpriv.vo_q);
507                         phwxmit = pxmitpriv->hwxmits;
508                         break;
509
510                 case 0:
511                 case 3:
512                 default:
513                         ptxservq = &(psta->sta_xmitpriv.be_q);
514                         phwxmit = pxmitpriv->hwxmits + 2;
515                         break;
516         }
517
518         _enter_critical_bh(&pxmitpriv->lock, &irqL);
519
520         xmitframe_phead = get_list_head(&ptxservq->sta_pending);
521         xmitframe_plist = get_next(xmitframe_phead);
522         while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE)
523         {
524                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
525                 xmitframe_plist = get_next(xmitframe_plist);
526
527                 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
528                 if (pbuf + len > MAX_XMITBUF_SZ) break;
529
530                 rtw_list_delete(&pxmitframe->list);
531                 ptxservq->qcnt--;
532                 phwxmit->accnt--;
533
534 #ifndef IDEA_CONDITION
535                 // suppose only data frames would be in queue
536                 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
537                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
538                                  ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
539                                   pxmitframe->frame_tag, DATA_FRAMETAG));
540                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
541                         continue;
542                 }
543
544                 // TID 0~15
545                 if ((pxmitframe->attrib.priority < 0) ||
546                     (pxmitframe->attrib.priority > 15)) {
547                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
548                                  ("xmitframe_complete: TID(%d) should be 0~15!\n",
549                                   pxmitframe->attrib.priority));
550                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
551                         continue;
552                 }
553 #endif
554
555 //              pxmitframe->pxmitbuf = pxmitbuf;
556                 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
557
558                 pxmitframe->agg_num = 0; // not first frame of aggregation
559                 pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset
560
561                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
562                         DBG_871X("%s coalesce failed \n",__FUNCTION__);
563                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
564                         continue;
565                 }
566
567
568                 // always return ndis_packet after rtw_xmitframe_coalesce
569                 rtw_os_xmit_complete(padapter, pxmitframe);
570
571                 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
572                 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
573
574                 // don't need xmitframe any more
575                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
576
577                 // handle pointer and stop condition
578                 pbuf_tail = pbuf + len;
579                 pbuf = _RND8(pbuf_tail);
580
581                 pfirstframe->agg_num++;
582                 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
583                         break;
584
585                 if (pbuf < bulkPtr) {
586                         descCount++;
587                         if (descCount == pHalData->UsbTxAggDescNum)
588                                 break;
589                 } else {
590                         descCount = 0;
591                         bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
592                 }
593         }
594         if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
595                 rtw_list_delete(&ptxservq->tx_pending);
596
597         _exit_critical_bh(&pxmitpriv->lock, &irqL);
598
599         if ((pfirstframe->attrib.ether_type != 0x0806) &&
600             (pfirstframe->attrib.ether_type != 0x888e) &&
601             (pfirstframe->attrib.dhcp_pkt != 1))
602         {
603                 rtw_issue_addbareq_cmd(padapter, pfirstframe);
604         }
605
606 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
607         //3 3. update first frame txdesc
608         if ((pbuf_tail % bulkSize) == 0) {
609                 // remove pkt_offset
610                 pbuf_tail -= PACKET_OFFSET_SZ;
611                 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
612                 pfirstframe->pkt_offset = 0;
613         }
614 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
615         update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
616
617         //3 4. write xmit buffer to USB FIFO
618         ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
619
620         // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
621         rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
622
623
624         //3 5. update statisitc
625         pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
626         if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
627         
628         rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
629
630         rtw_free_xmitframe(pxmitpriv, pfirstframe);
631
632         return _TRUE;
633 }
634
635 #else
636
637 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
638 {               
639
640         struct hw_xmit *phwxmits;
641         sint hwentry;
642         struct xmit_frame *pxmitframe=NULL;     
643         int res=_SUCCESS, xcnt = 0;
644
645         phwxmits = pxmitpriv->hwxmits;
646         hwentry = pxmitpriv->hwxmit_entry;
647
648         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
649
650         if(pxmitbuf==NULL)
651         {
652                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);                
653                 if(!pxmitbuf)
654                 {
655                         return _FALSE;
656                 }                       
657         }       
658
659
660         do
661         {               
662                 pxmitframe =  rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
663                 
664                 if(pxmitframe)
665                 {
666                         pxmitframe->pxmitbuf = pxmitbuf;                                
667
668                         pxmitframe->buf_addr = pxmitbuf->pbuf;
669
670                         pxmitbuf->priv_data = pxmitframe;       
671
672                         if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
673                         {       
674                                 if(pxmitframe->attrib.priority<=15)//TID0~15
675                                 {
676                                         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
677                                 }       
678                                                         
679                                 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce                     
680                         }       
681
682                                 
683                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
684
685                         
686                         if(res == _SUCCESS)
687                         {
688                                 rtw_dump_xframe(padapter, pxmitframe);
689                         }
690                         else
691                         {
692                                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
693                                 rtw_free_xmitframe(pxmitpriv, pxmitframe);      
694                         }
695                                                 
696                         xcnt++;
697                         
698                 }
699                 else
700                 {                       
701                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
702                         return _FALSE;
703                 }
704
705                 break;
706                 
707         }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
708
709         return _TRUE;
710         
711 }
712 #endif
713
714
715
716 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
717 {
718         s32 res = _SUCCESS;
719
720
721         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
722         if (res == _SUCCESS) {
723                 rtw_dump_xframe(padapter, pxmitframe);
724         }
725
726         return res;
727 }
728
729 /*
730  * Return
731  *      _TRUE   dump packet directly
732  *      _FALSE  enqueue packet
733  */
734 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
735 {
736         _irqL irqL;
737         s32 res;
738         struct xmit_buf *pxmitbuf = NULL;
739         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
740         struct pkt_attrib *pattrib = &pxmitframe->attrib;
741         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
742 #ifdef CONFIG_TDLS      
743         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
744         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
745         //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
746 #endif
747
748
749         _enter_critical_bh(&pxmitpriv->lock, &irqL);
750
751         if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
752                 goto enqueue;
753
754         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
755                 goto enqueue;
756
757 #ifdef CONFIG_CONCURRENT_MODE   
758         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
759                 goto enqueue;
760 #endif
761
762         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
763         if (pxmitbuf == NULL)
764                 goto enqueue;
765
766         _exit_critical_bh(&pxmitpriv->lock, &irqL);
767
768         pxmitframe->pxmitbuf = pxmitbuf;
769         pxmitframe->buf_addr = pxmitbuf->pbuf;
770         pxmitbuf->priv_data = pxmitframe;
771
772         if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
773                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
774                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
775         }
776
777         return _TRUE;
778
779 enqueue:
780         res = rtw_xmitframe_enqueue(padapter, pxmitframe);
781         _exit_critical_bh(&pxmitpriv->lock, &irqL);
782
783         if (res != _SUCCESS) {
784                 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
785                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
786
787                 pxmitpriv->tx_drop++;
788                 return _TRUE;
789         }
790
791         return _FALSE;
792 }
793
794 s32 rtl8723bu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
795 {
796         return rtw_dump_xframe(padapter, pmgntframe);
797 }
798
799 /*
800  * Return
801  *      _TRUE   dump packet directly ok
802  *      _FALSE  temporary can't transmit packets to hardware
803  */
804 s32 rtl8723bu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
805 {
806         return pre_xmitframe(padapter, pxmitframe);
807 }
808
809 s32     rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
810 {
811         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
812         s32 err;
813         
814         if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) 
815         {
816                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
817
818                 pxmitpriv->tx_drop++;                                   
819         }
820         else
821         {
822 #ifdef PLATFORM_LINUX
823                 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
824 #endif
825         }
826         
827         return err;
828         
829 }
830
831
832 #ifdef  CONFIG_HOSTAPD_MLME
833
834 static void rtl8723bu_hostap_mgnt_xmit_cb(struct urb *urb)
835 {       
836 #ifdef PLATFORM_LINUX
837         struct sk_buff *skb = (struct sk_buff *)urb->context;
838
839         //DBG_8192C("%s\n", __FUNCTION__);
840
841         rtw_skb_free(skb);
842 #endif  
843 }
844
845 s32 rtl8723bu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
846 {
847 #ifdef PLATFORM_LINUX
848         u16 fc;
849         int rc, len, pipe;      
850         unsigned int bmcst, tid, qsel;
851         struct sk_buff *skb, *pxmit_skb;
852         struct urb *urb;
853         unsigned char *pxmitbuf;
854         struct tx_desc *ptxdesc;
855         struct ieee80211_hdr *tx_hdr;
856         struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;     
857         struct net_device *pnetdev = padapter->pnetdev;
858         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
859         struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); 
860
861         
862         //DBG_8192C("%s\n", __FUNCTION__);
863
864         skb = pkt;
865         
866         len = skb->len;
867         tx_hdr = (struct ieee80211_hdr *)(skb->data);
868         fc = le16_to_cpu(tx_hdr->frame_ctl);
869         bmcst = IS_MCAST(tx_hdr->addr1);
870
871         if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
872                 goto _exit;
873
874         pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
875
876         if(!pxmit_skb)
877                 goto _exit;
878
879         pxmitbuf = pxmit_skb->data;
880
881         urb = usb_alloc_urb(0, GFP_ATOMIC);
882         if (!urb) {
883                 goto _exit;
884         }
885
886         // ----- fill tx desc -----     
887         ptxdesc = (struct tx_desc *)pxmitbuf;   
888         _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
889                 
890         //offset 0      
891         ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff); 
892         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
893         ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
894
895         if(bmcst)       
896         {
897                 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
898         }       
899
900         //offset 4      
901         ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
902
903         ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
904
905         ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
906
907         //offset 8                      
908
909         //offset 12             
910         ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
911
912         //offset 16             
913         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
914                 
915         //offset 20
916
917
918         //HW append seq
919         ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
920         ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
921         
922
923         rtl8192cu_cal_txdesc_chksum(ptxdesc);
924         // ----- end of fill tx desc -----
925
926         //
927         skb_put(pxmit_skb, len + TXDESC_SIZE);
928         pxmitbuf = pxmitbuf + TXDESC_SIZE;
929         _rtw_memcpy(pxmitbuf, skb->data, len);
930
931         //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
932
933
934         // ----- prepare urb for submit -----
935         
936         //translate DMA FIFO addr to pipehandle
937         //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
938         pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
939         
940         usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
941                           pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
942         
943         urb->transfer_flags |= URB_ZERO_PACKET;
944         usb_anchor_urb(urb, &phostapdpriv->anchored);
945         rc = usb_submit_urb(urb, GFP_ATOMIC);
946         if (rc < 0) {
947                 usb_unanchor_urb(urb);
948                 kfree_skb(skb);
949         }
950         usb_free_urb(urb);
951
952         
953 _exit:  
954         
955         rtw_skb_free(skb);
956
957 #endif
958
959         return 0;
960
961 }
962 #endif
963