8723BU: Update 8723BU wifi driver to version v4.3.16_14189.20150519_BTCOEX2015119...
[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
186         struct ht_priv          *phtpriv = &pmlmepriv->htpriv;
187         struct mlme_ext_priv    *pmlmeext = &padapter->mlmeextpriv;
188         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
189         sint    bmcst = IS_MCAST(pattrib->ra);
190 #ifdef CONFIG_P2P
191         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
192 #endif //CONFIG_P2P
193 #endif
194 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
195         if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
196         {
197                 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
198                 pull = 1;
199                 pxmitframe->pkt_offset --;
200
201         }
202 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
203
204         _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
205
206         rtl8723b_update_txdesc(pxmitframe, (u8 *)ptxdesc);
207         _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc);
208         return pull;
209                 
210 }
211
212 #ifdef CONFIG_XMIT_THREAD_MODE
213 /*
214  * Description
215  *      Transmit xmitbuf to hardware tx fifo
216  *
217  * Return
218  *      _SUCCESS        ok
219  *      _FAIL           something error
220  */
221 s32 rtl8723bu_xmit_buf_handler(PADAPTER padapter)
222 {
223         //PHAL_DATA_TYPE phal;
224         struct xmit_priv *pxmitpriv;
225         struct xmit_buf *pxmitbuf;
226         s32 ret;
227
228
229         //phal = GET_HAL_DATA(padapter);
230         pxmitpriv = &padapter->xmitpriv;
231
232         ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
233         if (_FAIL == ret) {
234                 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
235                                  ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
236                 return _FAIL;
237         }
238
239         ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
240         if (ret) {
241                 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
242                                  ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
243                                   __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
244                 return _FAIL;
245         }
246
247         if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
248                 return _SUCCESS;
249
250 #ifdef CONFIG_LPS_LCLK
251         ret = rtw_register_tx_alive(padapter);
252         if (ret != _SUCCESS) {
253                 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
254                                  ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
255                 return _SUCCESS;
256         }
257 #endif
258
259         do {
260                 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
261                 if (pxmitbuf == NULL) break;
262
263                 rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);
264
265         } while (1);
266
267 #ifdef CONFIG_LPS_LCLK
268         rtw_unregister_tx_alive(padapter);
269 #endif
270
271         return _SUCCESS;
272 }
273 #endif
274
275
276 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
277 {
278         s32 ret = _SUCCESS;
279         s32 inner_ret = _SUCCESS;
280         int t, sz, w_sz, pull=0;
281         u8 *mem_addr;
282         u32 ff_hwaddr;
283         struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
284         struct pkt_attrib *pattrib = &pxmitframe->attrib;
285         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
286         struct security_priv *psecuritypriv = &padapter->securitypriv;
287
288         if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
289             (pxmitframe->attrib.ether_type != 0x0806) &&
290             (pxmitframe->attrib.ether_type != 0x888e) &&
291             (pxmitframe->attrib.dhcp_pkt != 1))
292         {
293                 rtw_issue_addbareq_cmd(padapter, pxmitframe);
294         }
295         
296         mem_addr = pxmitframe->buf_addr;
297
298        RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
299         
300         for (t = 0; t < pattrib->nr_frags; t++)
301         {
302                 if (inner_ret != _SUCCESS && ret == _SUCCESS)
303                         ret = _FAIL;
304
305                 if (t != (pattrib->nr_frags - 1))
306                 {
307                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
308
309                         sz = pxmitpriv->frag_len;
310                         sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);                                       
311                 }
312                 else //no frag
313                 {
314                         sz = pattrib->last_txcmdsz;
315                 }
316
317                 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
318 //              rtl8723b_update_txdesc(pxmitframe, mem_addr+PACKET_OFFSET_SZ);
319
320                 if(pull)
321                 {
322                         mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
323                         
324                         //pxmitbuf ->pbuf = mem_addr;                   
325                         pxmitframe->buf_addr = mem_addr;
326
327                         w_sz = sz + TXDESC_SIZE;
328                 }
329                 else
330                 {
331                         w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
332                 }       
333
334                 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
335 #ifdef CONFIG_XMIT_THREAD_MODE
336                 pxmitbuf->len = w_sz;
337                 pxmitbuf->ff_hwaddr = ff_hwaddr;
338                 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
339 #else
340                 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
341 #endif
342                 rtw_count_tx_stats(padapter, pxmitframe, sz);
343
344
345                 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
346                 //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);      
347
348                 mem_addr += w_sz;
349
350                 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
351
352         }
353         
354         rtw_free_xmitframe(pxmitpriv, pxmitframe);
355
356         if  (ret != _SUCCESS)
357                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
358
359         return ret;     
360 }
361
362 #ifdef CONFIG_USB_TX_AGGREGATION
363 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
364 {
365         struct pkt_attrib *pattrib = &pxmitframe->attrib;
366
367         u32     len = 0;
368
369         // no consider fragement
370         len = pattrib->hdrlen + pattrib->iv_len +
371                 SNAP_SIZE + sizeof(u16) +
372                 pattrib->pktlen +
373                 ((pattrib->bswenc) ? pattrib->icv_len : 0);
374
375         if(pattrib->encrypt ==_TKIP_)
376                 len += 8;
377
378         return len;
379 }
380
381 #define IDEA_CONDITION 1        // check all packets before enqueue
382 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
383 {
384         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
385         struct xmit_frame *pxmitframe = NULL;
386         struct xmit_frame *pfirstframe = NULL;
387
388         // aggregate variable
389         struct hw_xmit *phwxmit;
390         struct sta_info *psta = NULL;
391         struct tx_servq *ptxservq = NULL;
392
393         _irqL irqL;
394         _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
395
396         u32     pbuf;   // next pkt address
397         u32     pbuf_tail;      // last pkt tail
398         u32     len;    // packet length, except TXDESC_SIZE and PKT_OFFSET
399
400         u32     bulkSize = pHalData->UsbBulkOutSize;
401         u8      descCount;
402         u32     bulkPtr;
403
404         // dump frame variable
405         u32 ff_hwaddr;
406
407 #ifndef IDEA_CONDITION
408         int res = _SUCCESS;
409 #endif
410
411         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
412
413
414         // check xmitbuffer is ok
415         if (pxmitbuf == NULL) {
416                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
417                 if (pxmitbuf == NULL) return _FALSE;
418         }
419
420
421         //3 1. pick up first frame
422         do {
423                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
424                         
425                 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
426                 if (pxmitframe == NULL) {
427                         // no more xmit frame, release xmit buffer
428                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
429                         return _FALSE;
430                 }
431
432
433 #ifndef IDEA_CONDITION
434                 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
435                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
436                                  ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
437                                   pxmitframe->frame_tag, DATA_FRAMETAG));
438 //                      rtw_free_xmitframe(pxmitpriv, pxmitframe);
439                         continue;
440                 }
441
442                 // TID 0~15
443                 if ((pxmitframe->attrib.priority < 0) ||
444                     (pxmitframe->attrib.priority > 15)) {
445                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
446                                  ("xmitframe_complete: TID(%d) should be 0~15!\n",
447                                   pxmitframe->attrib.priority));
448 //                      rtw_free_xmitframe(pxmitpriv, pxmitframe);
449                         continue;
450                 }
451 #endif
452
453                 pxmitframe->pxmitbuf = pxmitbuf;
454                 pxmitframe->buf_addr = pxmitbuf->pbuf;
455                 pxmitbuf->priv_data = pxmitframe;
456
457                 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
458                 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
459
460                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
461                         DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
462                         continue;
463                 }
464
465
466                 // always return ndis_packet after rtw_xmitframe_coalesce
467                 rtw_os_xmit_complete(padapter, pxmitframe);
468
469                 break;
470         } while (1);
471
472         //3 2. aggregate same priority and same DA(AP or STA) frames
473         pfirstframe = pxmitframe;
474         len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
475         pbuf_tail = len;
476         pbuf = _RND8(pbuf_tail);
477
478         // check pkt amount in one bluk
479         descCount = 0;
480         bulkPtr = bulkSize;
481         if (pbuf < bulkPtr)
482                 descCount++;
483         else {
484                 descCount = 0;
485                 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
486         }
487
488         // dequeue same priority packet from station tx queue
489         psta = pfirstframe->attrib.psta;
490         switch (pfirstframe->attrib.priority) {
491                 case 1:
492                 case 2:
493                         ptxservq = &(psta->sta_xmitpriv.bk_q);
494                         phwxmit = pxmitpriv->hwxmits + 3;
495                         break;
496
497                 case 4:
498                 case 5:
499                         ptxservq = &(psta->sta_xmitpriv.vi_q);
500                         phwxmit = pxmitpriv->hwxmits + 1;
501                         break;
502
503                 case 6:
504                 case 7:
505                         ptxservq = &(psta->sta_xmitpriv.vo_q);
506                         phwxmit = pxmitpriv->hwxmits;
507                         break;
508
509                 case 0:
510                 case 3:
511                 default:
512                         ptxservq = &(psta->sta_xmitpriv.be_q);
513                         phwxmit = pxmitpriv->hwxmits + 2;
514                         break;
515         }
516
517         _enter_critical_bh(&pxmitpriv->lock, &irqL);
518
519         xmitframe_phead = get_list_head(&ptxservq->sta_pending);
520         xmitframe_plist = get_next(xmitframe_phead);
521         while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE)
522         {
523                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
524                 xmitframe_plist = get_next(xmitframe_plist);
525
526                 if(_FAIL == rtw_hal_busagg_qsel_check(padapter,pfirstframe->attrib.qsel,pxmitframe->attrib.qsel))
527                         break;
528                 
529                 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
530                 if (pbuf + len > MAX_XMITBUF_SZ) break;
531
532                 rtw_list_delete(&pxmitframe->list);
533                 ptxservq->qcnt--;
534                 phwxmit->accnt--;
535
536 #ifndef IDEA_CONDITION
537                 // suppose only data frames would be in queue
538                 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
539                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
540                                  ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
541                                   pxmitframe->frame_tag, DATA_FRAMETAG));
542                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
543                         continue;
544                 }
545
546                 // TID 0~15
547                 if ((pxmitframe->attrib.priority < 0) ||
548                     (pxmitframe->attrib.priority > 15)) {
549                         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
550                                  ("xmitframe_complete: TID(%d) should be 0~15!\n",
551                                   pxmitframe->attrib.priority));
552                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
553                         continue;
554                 }
555 #endif
556
557 //              pxmitframe->pxmitbuf = pxmitbuf;
558                 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
559
560                 pxmitframe->agg_num = 0; // not first frame of aggregation
561                 pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset
562
563                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
564                         DBG_871X("%s coalesce failed \n",__FUNCTION__);
565                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
566                         continue;
567                 }
568
569
570                 // always return ndis_packet after rtw_xmitframe_coalesce
571                 rtw_os_xmit_complete(padapter, pxmitframe);
572
573                 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
574                 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
575
576                 // don't need xmitframe any more
577                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
578
579                 // handle pointer and stop condition
580                 pbuf_tail = pbuf + len;
581                 pbuf = _RND8(pbuf_tail);
582
583                 pfirstframe->agg_num++;
584                 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
585                         break;
586
587                 if (pbuf < bulkPtr) {
588                         descCount++;
589                         if (descCount == pHalData->UsbTxAggDescNum)
590                                 break;
591                 } else {
592                         descCount = 0;
593                         bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
594                 }
595         }
596         if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
597                 rtw_list_delete(&ptxservq->tx_pending);
598
599         _exit_critical_bh(&pxmitpriv->lock, &irqL);
600
601         if ((pfirstframe->attrib.ether_type != 0x0806) &&
602             (pfirstframe->attrib.ether_type != 0x888e) &&
603             (pfirstframe->attrib.dhcp_pkt != 1))
604         {
605                 rtw_issue_addbareq_cmd(padapter, pfirstframe);
606         }
607
608 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
609         //3 3. update first frame txdesc
610         if ((pbuf_tail % bulkSize) == 0) {
611                 // remove pkt_offset
612                 pbuf_tail -= PACKET_OFFSET_SZ;
613                 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
614                 pfirstframe->pkt_offset = 0;
615         }
616 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
617         update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
618
619         //3 4. write xmit buffer to USB FIFO
620         ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
621
622         // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
623         rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
624
625
626         //3 5. update statisitc
627         pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
628         if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
629         
630         rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
631
632         rtw_free_xmitframe(pxmitpriv, pfirstframe);
633
634         return _TRUE;
635 }
636
637 #else
638
639 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
640 {               
641
642         struct hw_xmit *phwxmits;
643         sint hwentry;
644         struct xmit_frame *pxmitframe=NULL;     
645         int res=_SUCCESS, xcnt = 0;
646
647         phwxmits = pxmitpriv->hwxmits;
648         hwentry = pxmitpriv->hwxmit_entry;
649
650         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
651
652         if(pxmitbuf==NULL)
653         {
654                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);                
655                 if(!pxmitbuf)
656                 {
657                         return _FALSE;
658                 }                       
659         }       
660
661
662         do
663         {               
664                 pxmitframe =  rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
665                 
666                 if(pxmitframe)
667                 {
668                         pxmitframe->pxmitbuf = pxmitbuf;                                
669
670                         pxmitframe->buf_addr = pxmitbuf->pbuf;
671
672                         pxmitbuf->priv_data = pxmitframe;       
673
674                         if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
675                         {       
676                                 if(pxmitframe->attrib.priority<=15)//TID0~15
677                                 {
678                                         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
679                                 }       
680                                                         
681                                 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce                     
682                         }       
683
684                                 
685                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
686
687                         
688                         if(res == _SUCCESS)
689                         {
690                                 rtw_dump_xframe(padapter, pxmitframe);
691                         }
692                         else
693                         {
694                                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
695                                 rtw_free_xmitframe(pxmitpriv, pxmitframe);      
696                         }
697                                                 
698                         xcnt++;
699                         
700                 }
701                 else
702                 {                       
703                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
704                         return _FALSE;
705                 }
706
707                 break;
708                 
709         }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
710
711         return _TRUE;
712         
713 }
714 #endif
715
716
717
718 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
719 {
720         s32 res = _SUCCESS;
721
722
723         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
724         if (res == _SUCCESS) {
725                 rtw_dump_xframe(padapter, pxmitframe);
726         }
727
728         return res;
729 }
730
731 /*
732  * Return
733  *      _TRUE   dump packet directly
734  *      _FALSE  enqueue packet
735  */
736 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
737 {
738         _irqL irqL;
739         s32 res;
740         struct xmit_buf *pxmitbuf = NULL;
741         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
742         struct pkt_attrib *pattrib = &pxmitframe->attrib;
743         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
744 #ifdef CONFIG_TDLS      
745         struct mlme_ext_priv    *pmlmeext = &(padapter->mlmeextpriv);
746         struct mlme_ext_info    *pmlmeinfo = &(pmlmeext->mlmext_info);
747         //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
748 #endif
749
750         _enter_critical_bh(&pxmitpriv->lock, &irqL);
751
752         if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
753                 goto enqueue;
754
755         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
756                 goto enqueue;
757
758 #ifdef CONFIG_CONCURRENT_MODE   
759         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
760                 goto enqueue;
761 #endif
762
763         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
764         if (pxmitbuf == NULL)
765                 goto enqueue;
766
767         _exit_critical_bh(&pxmitpriv->lock, &irqL);
768
769         pxmitframe->pxmitbuf = pxmitbuf;
770         pxmitframe->buf_addr = pxmitbuf->pbuf;
771         pxmitbuf->priv_data = pxmitframe;
772
773         if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
774                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
775                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
776         }
777
778         return _TRUE;
779
780 enqueue:
781         res = rtw_xmitframe_enqueue(padapter, pxmitframe);
782         _exit_critical_bh(&pxmitpriv->lock, &irqL);
783
784         if (res != _SUCCESS) {
785                 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
786                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
787
788                 pxmitpriv->tx_drop++;
789                 return _TRUE;
790         }
791
792         return _FALSE;
793 }
794
795 s32 rtl8723bu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
796 {
797         return rtw_dump_xframe(padapter, pmgntframe);
798 }
799
800 /*
801  * Return
802  *      _TRUE   dump packet directly ok
803  *      _FALSE  temporary can't transmit packets to hardware
804  */
805 s32 rtl8723bu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
806 {
807         return pre_xmitframe(padapter, pxmitframe);
808 }
809
810 s32     rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
811 {
812         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
813         s32 err;
814         
815         if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) 
816         {
817                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
818
819                 pxmitpriv->tx_drop++;                                   
820         }
821         else
822         {
823 #ifdef PLATFORM_LINUX
824                 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
825 #endif
826         }
827         
828         return err;
829         
830 }
831
832
833 #ifdef  CONFIG_HOSTAPD_MLME
834
835 static void rtl8723bu_hostap_mgnt_xmit_cb(struct urb *urb)
836 {       
837 #ifdef PLATFORM_LINUX
838         struct sk_buff *skb = (struct sk_buff *)urb->context;
839
840         //DBG_8192C("%s\n", __FUNCTION__);
841
842         rtw_skb_free(skb);
843 #endif  
844 }
845
846 s32 rtl8723bu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
847 {
848 #ifdef PLATFORM_LINUX
849         u16 fc;
850         int rc, len, pipe;      
851         unsigned int bmcst, tid, qsel;
852         struct sk_buff *skb, *pxmit_skb;
853         struct urb *urb;
854         unsigned char *pxmitbuf;
855         struct tx_desc *ptxdesc;
856         struct ieee80211_hdr *tx_hdr;
857         struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;     
858         struct net_device *pnetdev = padapter->pnetdev;
859         HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
860         struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter); 
861
862         
863         //DBG_8192C("%s\n", __FUNCTION__);
864
865         skb = pkt;
866         
867         len = skb->len;
868         tx_hdr = (struct ieee80211_hdr *)(skb->data);
869         fc = le16_to_cpu(tx_hdr->frame_ctl);
870         bmcst = IS_MCAST(tx_hdr->addr1);
871
872         if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
873                 goto _exit;
874
875         pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
876
877         if(!pxmit_skb)
878                 goto _exit;
879
880         pxmitbuf = pxmit_skb->data;
881
882         urb = usb_alloc_urb(0, GFP_ATOMIC);
883         if (!urb) {
884                 goto _exit;
885         }
886
887         // ----- fill tx desc -----     
888         ptxdesc = (struct tx_desc *)pxmitbuf;   
889         _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
890                 
891         //offset 0      
892         ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff); 
893         ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
894         ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
895
896         if(bmcst)       
897         {
898                 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
899         }       
900
901         //offset 4      
902         ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
903
904         ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
905
906         ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
907
908         //offset 8                      
909
910         //offset 12             
911         ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
912
913         //offset 16             
914         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
915                 
916         //offset 20
917
918
919         //HW append seq
920         ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
921         ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
922         
923
924         rtl8723b_cal_txdesc_chksum(ptxdesc);
925         // ----- end of fill tx desc -----
926
927         //
928         skb_put(pxmit_skb, len + TXDESC_SIZE);
929         pxmitbuf = pxmitbuf + TXDESC_SIZE;
930         _rtw_memcpy(pxmitbuf, skb->data, len);
931
932         //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
933
934
935         // ----- prepare urb for submit -----
936         
937         //translate DMA FIFO addr to pipehandle
938         //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
939         pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
940         
941         usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
942                           pxmit_skb->data, pxmit_skb->len, rtl8723bu_hostap_mgnt_xmit_cb, pxmit_skb);
943         
944         urb->transfer_flags |= URB_ZERO_PACKET;
945         usb_anchor_urb(urb, &phostapdpriv->anchored);
946         rc = usb_submit_urb(urb, GFP_ATOMIC);
947         if (rc < 0) {
948                 usb_unanchor_urb(urb);
949                 kfree_skb(skb);
950         }
951         usb_free_urb(urb);
952
953         
954 _exit:  
955         
956         rtw_skb_free(skb);
957
958 #endif
959
960         return 0;
961
962 }
963 #endif
964