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 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
528 if (pbuf + len > MAX_XMITBUF_SZ) break;
530 rtw_list_delete(&pxmitframe->list);
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);
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);
555 // pxmitframe->pxmitbuf = pxmitbuf;
556 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
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
561 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
562 DBG_871X("%s coalesce failed \n",__FUNCTION__);
563 rtw_free_xmitframe(pxmitpriv, pxmitframe);
568 // always return ndis_packet after rtw_xmitframe_coalesce
569 rtw_os_xmit_complete(padapter, pxmitframe);
571 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
572 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
574 // don't need xmitframe any more
575 rtw_free_xmitframe(pxmitpriv, pxmitframe);
577 // handle pointer and stop condition
578 pbuf_tail = pbuf + len;
579 pbuf = _RND8(pbuf_tail);
581 pfirstframe->agg_num++;
582 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
585 if (pbuf < bulkPtr) {
587 if (descCount == pHalData->UsbTxAggDescNum)
591 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
594 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
595 rtw_list_delete(&ptxservq->tx_pending);
597 _exit_critical_bh(&pxmitpriv->lock, &irqL);
599 if ((pfirstframe->attrib.ether_type != 0x0806) &&
600 (pfirstframe->attrib.ether_type != 0x888e) &&
601 (pfirstframe->attrib.dhcp_pkt != 1))
603 rtw_issue_addbareq_cmd(padapter, pfirstframe);
606 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
607 //3 3. update first frame txdesc
608 if ((pbuf_tail % bulkSize) == 0) {
610 pbuf_tail -= PACKET_OFFSET_SZ;
611 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
612 pfirstframe->pkt_offset = 0;
614 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
615 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
617 //3 4. write xmit buffer to USB FIFO
618 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
620 // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
621 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
624 //3 5. update statisitc
625 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
626 if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
628 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
630 rtw_free_xmitframe(pxmitpriv, pfirstframe);
637 s32 rtl8723bu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
640 struct hw_xmit *phwxmits;
642 struct xmit_frame *pxmitframe=NULL;
643 int res=_SUCCESS, xcnt = 0;
645 phwxmits = pxmitpriv->hwxmits;
646 hwentry = pxmitpriv->hwxmit_entry;
648 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
652 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
662 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
666 pxmitframe->pxmitbuf = pxmitbuf;
668 pxmitframe->buf_addr = pxmitbuf->pbuf;
670 pxmitbuf->priv_data = pxmitframe;
672 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
674 if(pxmitframe->attrib.priority<=15)//TID0~15
676 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
679 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
683 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
688 rtw_dump_xframe(padapter, pxmitframe);
692 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
693 rtw_free_xmitframe(pxmitpriv, pxmitframe);
701 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
707 }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
716 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
721 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
722 if (res == _SUCCESS) {
723 rtw_dump_xframe(padapter, pxmitframe);
731 * _TRUE dump packet directly
732 * _FALSE enqueue packet
734 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
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;
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);
749 _enter_critical_bh(&pxmitpriv->lock, &irqL);
751 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
754 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
757 #ifdef CONFIG_CONCURRENT_MODE
758 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
762 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
763 if (pxmitbuf == NULL)
766 _exit_critical_bh(&pxmitpriv->lock, &irqL);
768 pxmitframe->pxmitbuf = pxmitbuf;
769 pxmitframe->buf_addr = pxmitbuf->pbuf;
770 pxmitbuf->priv_data = pxmitframe;
772 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
773 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
774 rtw_free_xmitframe(pxmitpriv, pxmitframe);
780 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
781 _exit_critical_bh(&pxmitpriv->lock, &irqL);
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);
787 pxmitpriv->tx_drop++;
794 s32 rtl8723bu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
796 return rtw_dump_xframe(padapter, pmgntframe);
801 * _TRUE dump packet directly ok
802 * _FALSE temporary can't transmit packets to hardware
804 s32 rtl8723bu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
806 return pre_xmitframe(padapter, pxmitframe);
809 s32 rtl8723bu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
811 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
814 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
816 rtw_free_xmitframe(pxmitpriv, pxmitframe);
818 pxmitpriv->tx_drop++;
822 #ifdef PLATFORM_LINUX
823 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
832 #ifdef CONFIG_HOSTAPD_MLME
834 static void rtl8723bu_hostap_mgnt_xmit_cb(struct urb *urb)
836 #ifdef PLATFORM_LINUX
837 struct sk_buff *skb = (struct sk_buff *)urb->context;
839 //DBG_8192C("%s\n", __FUNCTION__);
845 s32 rtl8723bu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
847 #ifdef PLATFORM_LINUX
850 unsigned int bmcst, tid, qsel;
851 struct sk_buff *skb, *pxmit_skb;
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);
862 //DBG_8192C("%s\n", __FUNCTION__);
867 tx_hdr = (struct ieee80211_hdr *)(skb->data);
868 fc = le16_to_cpu(tx_hdr->frame_ctl);
869 bmcst = IS_MCAST(tx_hdr->addr1);
871 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
874 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
879 pxmitbuf = pxmit_skb->data;
881 urb = usb_alloc_urb(0, GFP_ATOMIC);
886 // ----- fill tx desc -----
887 ptxdesc = (struct tx_desc *)pxmitbuf;
888 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
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);
897 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
901 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
903 ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
905 ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
910 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
913 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
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.
923 rtl8192cu_cal_txdesc_chksum(ptxdesc);
924 // ----- end of fill tx desc -----
927 skb_put(pxmit_skb, len + TXDESC_SIZE);
928 pxmitbuf = pxmitbuf + TXDESC_SIZE;
929 _rtw_memcpy(pxmitbuf, skb->data, len);
931 //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
934 // ----- prepare urb for submit -----
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);
940 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
941 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
943 urb->transfer_flags |= URB_ZERO_PACKET;
944 usb_anchor_urb(urb, &phostapdpriv->anchored);
945 rc = usb_submit_urb(urb, GFP_ATOMIC);
947 usb_unanchor_urb(urb);