1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
21 #define _RTL8723BU_XMIT_C_
23 #include <rtl8723b_hal.h>
26 s32 rtl8723bu_init_xmit_priv(_adapter *padapter)
28 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
31 tasklet_init(&pxmitpriv->xmit_tasklet,
32 (void(*)(unsigned long))rtl8723bu_xmit_tasklet,
33 (unsigned long)padapter);
38 void rtl8723bu_free_xmit_priv(_adapter *padapter)
42 void _dbg_dump_tx_info(_adapter *padapter,int frame_tag,struct tx_desc *ptxdesc)
45 u8 bDumpTxDesc = _FALSE;
46 rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(bDumpTxPkt));
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){
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){
60 else if(bDumpTxPkt ==3){//dump early info
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");
80 int urb_zero_packet_chk(_adapter *padapter, int sz)
82 u8 blnSetTxDescOffset;
83 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
84 blnSetTxDescOffset = (((sz + TXDESC_SIZE) % pHalData->UsbBulkOutSize) ==0)?1:0;
86 return blnSetTxDescOffset;
88 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
90 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
92 switch (pattrib->encrypt)
97 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
101 //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
102 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
105 ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
117 void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
119 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
121 switch(pattrib->vcs_mode)
124 *pdw |= cpu_to_le32(BIT(12));
127 *pdw |= cpu_to_le32(BIT(11));
134 if(pattrib->vcs_mode) {
135 *pdw |= cpu_to_le32(BIT(13));
140 *pdw |= (pattrib->bwmode&CHANNEL_WIDTH_40)? cpu_to_le32(BIT(27)):0;
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)
149 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
154 void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
156 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
160 *pdw |= (pattrib->bwmode&CHANNEL_WIDTH_40)? cpu_to_le32(BIT(25)):0;
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)
169 *pdw |= cpu_to_le32((0x03<<20)&0x003f0000);
173 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
178 _adapter *padapter = pxmitframe->padapter;
179 struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
182 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
183 struct pkt_attrib *pattrib = &pxmitframe->attrib;
184 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
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);
191 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
194 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
195 if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
197 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
199 pxmitframe->pkt_offset --;
202 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
204 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
206 rtl8723b_update_txdesc(pxmitframe, (u8 *)ptxdesc);
207 _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc);
212 #ifdef CONFIG_XMIT_THREAD_MODE
215 * Transmit xmitbuf to hardware tx fifo
219 * _FAIL something error
221 s32 rtl8723bu_xmit_buf_handler(PADAPTER padapter)
223 //PHAL_DATA_TYPE phal;
224 struct xmit_priv *pxmitpriv;
225 struct xmit_buf *pxmitbuf;
229 //phal = GET_HAL_DATA(padapter);
230 pxmitpriv = &padapter->xmitpriv;
232 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
234 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
235 ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
239 ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
241 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
242 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
243 __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
247 if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
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__));
260 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
261 if (pxmitbuf == NULL) break;
263 rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);
267 #ifdef CONFIG_LPS_LCLK
268 rtw_unregister_tx_alive(padapter);
276 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
279 s32 inner_ret = _SUCCESS;
280 int t, sz, w_sz, pull=0;
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;
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))
293 rtw_issue_addbareq_cmd(padapter, pxmitframe);
296 mem_addr = pxmitframe->buf_addr;
298 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
300 for (t = 0; t < pattrib->nr_frags; t++)
302 if (inner_ret != _SUCCESS && ret == _SUCCESS)
305 if (t != (pattrib->nr_frags - 1))
307 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
309 sz = pxmitpriv->frag_len;
310 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
314 sz = pattrib->last_txcmdsz;
317 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
318 // rtl8723b_update_txdesc(pxmitframe, mem_addr+PACKET_OFFSET_SZ);
322 mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
324 //pxmitbuf ->pbuf = mem_addr;
325 pxmitframe->buf_addr = mem_addr;
327 w_sz = sz + TXDESC_SIZE;
331 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
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);
340 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
342 rtw_count_tx_stats(padapter, pxmitframe, sz);
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);
350 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
354 rtw_free_xmitframe(pxmitpriv, pxmitframe);
357 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
362 #ifdef CONFIG_USB_TX_AGGREGATION
363 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
365 struct pkt_attrib *pattrib = &pxmitframe->attrib;
369 // no consider fragement
370 len = pattrib->hdrlen + pattrib->iv_len +
371 SNAP_SIZE + sizeof(u16) +
373 ((pattrib->bswenc) ? pattrib->icv_len : 0);
375 if(pattrib->encrypt ==_TKIP_)
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)
384 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
385 struct xmit_frame *pxmitframe = NULL;
386 struct xmit_frame *pfirstframe = NULL;
388 // aggregate variable
389 struct hw_xmit *phwxmit;
390 struct sta_info *psta = NULL;
391 struct tx_servq *ptxservq = NULL;
394 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
396 u32 pbuf; // next pkt address
397 u32 pbuf_tail; // last pkt tail
398 u32 len; // packet length, except TXDESC_SIZE and PKT_OFFSET
400 u32 bulkSize = pHalData->UsbBulkOutSize;
404 // dump frame variable
407 #ifndef IDEA_CONDITION
411 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
414 // check xmitbuffer is ok
415 if (pxmitbuf == NULL) {
416 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
417 if (pxmitbuf == NULL) return _FALSE;
421 //3 1. pick up first frame
423 rtw_free_xmitframe(pxmitpriv, pxmitframe);
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);
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);
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);
453 pxmitframe->pxmitbuf = pxmitbuf;
454 pxmitframe->buf_addr = pxmitbuf->pbuf;
455 pxmitbuf->priv_data = pxmitframe;
457 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
458 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
460 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
461 DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
466 // always return ndis_packet after rtw_xmitframe_coalesce
467 rtw_os_xmit_complete(padapter, pxmitframe);
472 //3 2. aggregate same priority and same DA(AP or STA) frames
473 pfirstframe = pxmitframe;
474 len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
476 pbuf = _RND8(pbuf_tail);
478 // check pkt amount in one bluk
485 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
488 // dequeue same priority packet from station tx queue
489 psta = pfirstframe->attrib.psta;
490 switch (pfirstframe->attrib.priority) {
493 ptxservq = &(psta->sta_xmitpriv.bk_q);
494 phwxmit = pxmitpriv->hwxmits + 3;
499 ptxservq = &(psta->sta_xmitpriv.vi_q);
500 phwxmit = pxmitpriv->hwxmits + 1;
505 ptxservq = &(psta->sta_xmitpriv.vo_q);
506 phwxmit = pxmitpriv->hwxmits;
512 ptxservq = &(psta->sta_xmitpriv.be_q);
513 phwxmit = pxmitpriv->hwxmits + 2;
517 _enter_critical_bh(&pxmitpriv->lock, &irqL);
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)
523 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
524 xmitframe_plist = get_next(xmitframe_plist);
526 if(_FAIL == rtw_hal_busagg_qsel_check(padapter,pfirstframe->attrib.qsel,pxmitframe->attrib.qsel))
529 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
530 if (pbuf + len > MAX_XMITBUF_SZ) break;
532 rtw_list_delete(&pxmitframe->list);
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);
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);
557 // pxmitframe->pxmitbuf = pxmitbuf;
558 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
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
563 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
564 DBG_871X("%s coalesce failed \n",__FUNCTION__);
565 rtw_free_xmitframe(pxmitpriv, pxmitframe);
570 // always return ndis_packet after rtw_xmitframe_coalesce
571 rtw_os_xmit_complete(padapter, pxmitframe);
573 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
574 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
576 // don't need xmitframe any more
577 rtw_free_xmitframe(pxmitpriv, pxmitframe);
579 // handle pointer and stop condition
580 pbuf_tail = pbuf + len;
581 pbuf = _RND8(pbuf_tail);
583 pfirstframe->agg_num++;
584 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
587 if (pbuf < bulkPtr) {
589 if (descCount == pHalData->UsbTxAggDescNum)
593 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
596 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
597 rtw_list_delete(&ptxservq->tx_pending);
599 _exit_critical_bh(&pxmitpriv->lock, &irqL);
601 if ((pfirstframe->attrib.ether_type != 0x0806) &&
602 (pfirstframe->attrib.ether_type != 0x888e) &&
603 (pfirstframe->attrib.dhcp_pkt != 1))
605 rtw_issue_addbareq_cmd(padapter, pfirstframe);
608 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
609 //3 3. update first frame txdesc
610 if ((pbuf_tail % bulkSize) == 0) {
612 pbuf_tail -= PACKET_OFFSET_SZ;
613 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
614 pfirstframe->pkt_offset = 0;
616 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
617 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
619 //3 4. write xmit buffer to USB FIFO
620 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
622 // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
623 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
626 //3 5. update statisitc
627 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
628 if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
630 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
632 rtw_free_xmitframe(pxmitpriv, pfirstframe);
639 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
642 struct hw_xmit *phwxmits;
644 struct xmit_frame *pxmitframe=NULL;
645 int res=_SUCCESS, xcnt = 0;
647 phwxmits = pxmitpriv->hwxmits;
648 hwentry = pxmitpriv->hwxmit_entry;
650 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
654 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
664 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
668 pxmitframe->pxmitbuf = pxmitbuf;
670 pxmitframe->buf_addr = pxmitbuf->pbuf;
672 pxmitbuf->priv_data = pxmitframe;
674 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
676 if(pxmitframe->attrib.priority<=15)//TID0~15
678 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
681 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
685 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
690 rtw_dump_xframe(padapter, pxmitframe);
694 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
695 rtw_free_xmitframe(pxmitpriv, pxmitframe);
703 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
709 }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
718 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
723 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
724 if (res == _SUCCESS) {
725 rtw_dump_xframe(padapter, pxmitframe);
733 * _TRUE dump packet directly
734 * _FALSE enqueue packet
736 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
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;
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);
750 _enter_critical_bh(&pxmitpriv->lock, &irqL);
752 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
755 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
758 #ifdef CONFIG_CONCURRENT_MODE
759 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
763 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
764 if (pxmitbuf == NULL)
767 _exit_critical_bh(&pxmitpriv->lock, &irqL);
769 pxmitframe->pxmitbuf = pxmitbuf;
770 pxmitframe->buf_addr = pxmitbuf->pbuf;
771 pxmitbuf->priv_data = pxmitframe;
773 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
774 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
775 rtw_free_xmitframe(pxmitpriv, pxmitframe);
781 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
782 _exit_critical_bh(&pxmitpriv->lock, &irqL);
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);
788 pxmitpriv->tx_drop++;
795 s32 rtl8723bu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
797 return rtw_dump_xframe(padapter, pmgntframe);
802 * _TRUE dump packet directly ok
803 * _FALSE temporary can't transmit packets to hardware
805 s32 rtl8723bu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
807 return pre_xmitframe(padapter, pxmitframe);
810 s32 rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
812 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
815 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
817 rtw_free_xmitframe(pxmitpriv, pxmitframe);
819 pxmitpriv->tx_drop++;
823 #ifdef PLATFORM_LINUX
824 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
833 #ifdef CONFIG_HOSTAPD_MLME
835 static void rtl8723bu_hostap_mgnt_xmit_cb(struct urb *urb)
837 #ifdef PLATFORM_LINUX
838 struct sk_buff *skb = (struct sk_buff *)urb->context;
840 //DBG_8192C("%s\n", __FUNCTION__);
846 s32 rtl8723bu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
848 #ifdef PLATFORM_LINUX
851 unsigned int bmcst, tid, qsel;
852 struct sk_buff *skb, *pxmit_skb;
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);
863 //DBG_8192C("%s\n", __FUNCTION__);
868 tx_hdr = (struct ieee80211_hdr *)(skb->data);
869 fc = le16_to_cpu(tx_hdr->frame_ctl);
870 bmcst = IS_MCAST(tx_hdr->addr1);
872 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
875 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
880 pxmitbuf = pxmit_skb->data;
882 urb = usb_alloc_urb(0, GFP_ATOMIC);
887 // ----- fill tx desc -----
888 ptxdesc = (struct tx_desc *)pxmitbuf;
889 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
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);
898 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
902 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
904 ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
906 ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
911 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
914 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
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.
924 rtl8723b_cal_txdesc_chksum(ptxdesc);
925 // ----- end of fill tx desc -----
928 skb_put(pxmit_skb, len + TXDESC_SIZE);
929 pxmitbuf = pxmitbuf + TXDESC_SIZE;
930 _rtw_memcpy(pxmitbuf, skb->data, len);
932 //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
935 // ----- prepare urb for submit -----
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);
941 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
942 pxmit_skb->data, pxmit_skb->len, rtl8723bu_hostap_mgnt_xmit_cb, pxmit_skb);
944 urb->transfer_flags |= URB_ZERO_PACKET;
945 usb_anchor_urb(urb, &phostapdpriv->anchored);
946 rc = usb_submit_urb(urb, GFP_ATOMIC);
948 usb_unanchor_urb(urb);