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);
185 struct dm_priv *pdmpriv = &pHalData->dmpriv;
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);
192 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
195 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
196 if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
198 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
200 pxmitframe->pkt_offset --;
203 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
205 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
207 rtl8723b_update_txdesc(pxmitframe, (u8 *)ptxdesc);
208 _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc);
213 #ifdef CONFIG_XMIT_THREAD_MODE
216 * Transmit xmitbuf to hardware tx fifo
220 * _FAIL something error
222 s32 rtl8723bu_xmit_buf_handler(PADAPTER padapter)
224 //PHAL_DATA_TYPE phal;
225 struct xmit_priv *pxmitpriv;
226 struct xmit_buf *pxmitbuf;
230 //phal = GET_HAL_DATA(padapter);
231 pxmitpriv = &padapter->xmitpriv;
233 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
235 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
236 ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
240 ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
242 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
243 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
244 __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
248 if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
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__));
261 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
262 if (pxmitbuf == NULL) break;
264 rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);
268 #ifdef CONFIG_LPS_LCLK
269 rtw_unregister_tx_alive(padapter);
277 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
280 s32 inner_ret = _SUCCESS;
281 int t, sz, w_sz, pull=0;
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;
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))
294 rtw_issue_addbareq_cmd(padapter, pxmitframe);
297 mem_addr = pxmitframe->buf_addr;
299 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
301 for (t = 0; t < pattrib->nr_frags; t++)
303 if (inner_ret != _SUCCESS && ret == _SUCCESS)
306 if (t != (pattrib->nr_frags - 1))
308 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
310 sz = pxmitpriv->frag_len;
311 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
315 sz = pattrib->last_txcmdsz;
318 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
319 // rtl8723b_update_txdesc(pxmitframe, mem_addr+PACKET_OFFSET_SZ);
323 mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
325 //pxmitbuf ->pbuf = mem_addr;
326 pxmitframe->buf_addr = mem_addr;
328 w_sz = sz + TXDESC_SIZE;
332 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
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);
341 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
343 rtw_count_tx_stats(padapter, pxmitframe, sz);
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);
351 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
355 rtw_free_xmitframe(pxmitpriv, pxmitframe);
358 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
363 #ifdef CONFIG_USB_TX_AGGREGATION
364 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
366 struct pkt_attrib *pattrib = &pxmitframe->attrib;
370 // no consider fragement
371 len = pattrib->hdrlen + pattrib->iv_len +
372 SNAP_SIZE + sizeof(u16) +
374 ((pattrib->bswenc) ? pattrib->icv_len : 0);
376 if(pattrib->encrypt ==_TKIP_)
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)
385 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
386 struct xmit_frame *pxmitframe = NULL;
387 struct xmit_frame *pfirstframe = NULL;
389 // aggregate variable
390 struct hw_xmit *phwxmit;
391 struct sta_info *psta = NULL;
392 struct tx_servq *ptxservq = NULL;
395 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
397 u32 pbuf; // next pkt address
398 u32 pbuf_tail; // last pkt tail
399 u32 len; // packet length, except TXDESC_SIZE and PKT_OFFSET
401 u32 bulkSize = pHalData->UsbBulkOutSize;
405 // dump frame variable
408 #ifndef IDEA_CONDITION
412 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
415 // check xmitbuffer is ok
416 if (pxmitbuf == NULL) {
417 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
418 if (pxmitbuf == NULL) return _FALSE;
422 //3 1. pick up first frame
424 rtw_free_xmitframe(pxmitpriv, pxmitframe);
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);
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);
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);
454 pxmitframe->pxmitbuf = pxmitbuf;
455 pxmitframe->buf_addr = pxmitbuf->pbuf;
456 pxmitbuf->priv_data = pxmitframe;
458 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
459 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
461 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
462 DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
467 // always return ndis_packet after rtw_xmitframe_coalesce
468 rtw_os_xmit_complete(padapter, pxmitframe);
473 //3 2. aggregate same priority and same DA(AP or STA) frames
474 pfirstframe = pxmitframe;
475 len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
477 pbuf = _RND8(pbuf_tail);
479 // check pkt amount in one bluk
486 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
489 // dequeue same priority packet from station tx queue
490 psta = pfirstframe->attrib.psta;
491 switch (pfirstframe->attrib.priority) {
494 ptxservq = &(psta->sta_xmitpriv.bk_q);
495 phwxmit = pxmitpriv->hwxmits + 3;
500 ptxservq = &(psta->sta_xmitpriv.vi_q);
501 phwxmit = pxmitpriv->hwxmits + 1;
506 ptxservq = &(psta->sta_xmitpriv.vo_q);
507 phwxmit = pxmitpriv->hwxmits;
513 ptxservq = &(psta->sta_xmitpriv.be_q);
514 phwxmit = pxmitpriv->hwxmits + 2;
518 _enter_critical_bh(&pxmitpriv->lock, &irqL);
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)
524 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
525 xmitframe_plist = get_next(xmitframe_plist);
527 if(_FAIL == rtw_hal_busagg_qsel_check(padapter,pfirstframe->attrib.qsel,pxmitframe->attrib.qsel))
530 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
531 if (pbuf + len > MAX_XMITBUF_SZ) break;
533 rtw_list_delete(&pxmitframe->list);
537 #ifndef IDEA_CONDITION
538 // suppose only data frames would be in queue
539 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
540 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
541 ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
542 pxmitframe->frame_tag, DATA_FRAMETAG));
543 rtw_free_xmitframe(pxmitpriv, pxmitframe);
548 if ((pxmitframe->attrib.priority < 0) ||
549 (pxmitframe->attrib.priority > 15)) {
550 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
551 ("xmitframe_complete: TID(%d) should be 0~15!\n",
552 pxmitframe->attrib.priority));
553 rtw_free_xmitframe(pxmitpriv, pxmitframe);
558 // pxmitframe->pxmitbuf = pxmitbuf;
559 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
561 pxmitframe->agg_num = 0; // not first frame of aggregation
562 pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset
564 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
565 DBG_871X("%s coalesce failed \n",__FUNCTION__);
566 rtw_free_xmitframe(pxmitpriv, pxmitframe);
571 // always return ndis_packet after rtw_xmitframe_coalesce
572 rtw_os_xmit_complete(padapter, pxmitframe);
574 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
575 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
577 // don't need xmitframe any more
578 rtw_free_xmitframe(pxmitpriv, pxmitframe);
580 // handle pointer and stop condition
581 pbuf_tail = pbuf + len;
582 pbuf = _RND8(pbuf_tail);
584 pfirstframe->agg_num++;
585 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
588 if (pbuf < bulkPtr) {
590 if (descCount == pHalData->UsbTxAggDescNum)
594 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
597 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
598 rtw_list_delete(&ptxservq->tx_pending);
600 _exit_critical_bh(&pxmitpriv->lock, &irqL);
602 if ((pfirstframe->attrib.ether_type != 0x0806) &&
603 (pfirstframe->attrib.ether_type != 0x888e) &&
604 (pfirstframe->attrib.dhcp_pkt != 1))
606 rtw_issue_addbareq_cmd(padapter, pfirstframe);
609 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
610 //3 3. update first frame txdesc
611 if ((pbuf_tail % bulkSize) == 0) {
613 pbuf_tail -= PACKET_OFFSET_SZ;
614 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
615 pfirstframe->pkt_offset = 0;
617 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
618 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
620 //3 4. write xmit buffer to USB FIFO
621 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
623 // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
624 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
627 //3 5. update statisitc
628 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
629 if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
631 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
633 rtw_free_xmitframe(pxmitpriv, pfirstframe);
640 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
643 struct hw_xmit *phwxmits;
645 struct xmit_frame *pxmitframe=NULL;
646 int res=_SUCCESS, xcnt = 0;
648 phwxmits = pxmitpriv->hwxmits;
649 hwentry = pxmitpriv->hwxmit_entry;
651 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
655 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
665 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
669 pxmitframe->pxmitbuf = pxmitbuf;
671 pxmitframe->buf_addr = pxmitbuf->pbuf;
673 pxmitbuf->priv_data = pxmitframe;
675 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
677 if(pxmitframe->attrib.priority<=15)//TID0~15
679 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
682 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
686 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
691 rtw_dump_xframe(padapter, pxmitframe);
695 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
696 rtw_free_xmitframe(pxmitpriv, pxmitframe);
704 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
710 }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
719 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
724 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
725 if (res == _SUCCESS) {
726 rtw_dump_xframe(padapter, pxmitframe);
734 * _TRUE dump packet directly
735 * _FALSE enqueue packet
737 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
741 struct xmit_buf *pxmitbuf = NULL;
742 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
743 struct pkt_attrib *pattrib = &pxmitframe->attrib;
744 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
746 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
747 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
748 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
751 _enter_critical_bh(&pxmitpriv->lock, &irqL);
753 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
756 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
759 #ifdef CONFIG_CONCURRENT_MODE
760 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
764 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
765 if (pxmitbuf == NULL)
768 _exit_critical_bh(&pxmitpriv->lock, &irqL);
770 pxmitframe->pxmitbuf = pxmitbuf;
771 pxmitframe->buf_addr = pxmitbuf->pbuf;
772 pxmitbuf->priv_data = pxmitframe;
774 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
775 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
776 rtw_free_xmitframe(pxmitpriv, pxmitframe);
782 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
783 _exit_critical_bh(&pxmitpriv->lock, &irqL);
785 if (res != _SUCCESS) {
786 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
787 rtw_free_xmitframe(pxmitpriv, pxmitframe);
789 pxmitpriv->tx_drop++;
796 s32 rtl8723bu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
798 return rtw_dump_xframe(padapter, pmgntframe);
803 * _TRUE dump packet directly ok
804 * _FALSE temporary can't transmit packets to hardware
806 s32 rtl8723bu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
808 return pre_xmitframe(padapter, pxmitframe);
811 s32 rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
813 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
816 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
818 rtw_free_xmitframe(pxmitpriv, pxmitframe);
820 pxmitpriv->tx_drop++;
824 #ifdef PLATFORM_LINUX
825 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
834 #ifdef CONFIG_HOSTAPD_MLME
836 static void rtl8723bu_hostap_mgnt_xmit_cb(struct urb *urb)
838 #ifdef PLATFORM_LINUX
839 struct sk_buff *skb = (struct sk_buff *)urb->context;
841 //DBG_8192C("%s\n", __FUNCTION__);
847 s32 rtl8723bu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
849 #ifdef PLATFORM_LINUX
852 unsigned int bmcst, tid, qsel;
853 struct sk_buff *skb, *pxmit_skb;
855 unsigned char *pxmitbuf;
856 struct tx_desc *ptxdesc;
857 struct ieee80211_hdr *tx_hdr;
858 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
859 struct net_device *pnetdev = padapter->pnetdev;
860 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
861 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
864 //DBG_8192C("%s\n", __FUNCTION__);
869 tx_hdr = (struct ieee80211_hdr *)(skb->data);
870 fc = le16_to_cpu(tx_hdr->frame_ctl);
871 bmcst = IS_MCAST(tx_hdr->addr1);
873 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
876 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
881 pxmitbuf = pxmit_skb->data;
883 urb = usb_alloc_urb(0, GFP_ATOMIC);
888 // ----- fill tx desc -----
889 ptxdesc = (struct tx_desc *)pxmitbuf;
890 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
893 ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff);
894 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
895 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
899 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
903 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
905 ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
907 ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
912 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
915 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
921 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
922 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
925 rtl8192cu_cal_txdesc_chksum(ptxdesc);
926 // ----- end of fill tx desc -----
929 skb_put(pxmit_skb, len + TXDESC_SIZE);
930 pxmitbuf = pxmitbuf + TXDESC_SIZE;
931 _rtw_memcpy(pxmitbuf, skb->data, len);
933 //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
936 // ----- prepare urb for submit -----
938 //translate DMA FIFO addr to pipehandle
939 //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
940 pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
942 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
943 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
945 urb->transfer_flags |= URB_ZERO_PACKET;
946 usb_anchor_urb(urb, &phostapdpriv->anchored);
947 rc = usb_submit_urb(urb, GFP_ATOMIC);
949 usb_unanchor_urb(urb);