1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 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 ******************************************************************************/
20 #define _RTL8192C_XMIT_C_
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <rtw_byteorder.h>
26 #include <osdep_intf.h>
29 //#include <rtl8192c_hal.h>
30 #include <rtl8723a_hal.h>
31 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
32 #error "Shall be Linux or Windows, but not both!\n"
36 s32 rtl8192cu_init_xmit_priv(_adapter *padapter)
38 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
41 tasklet_init(&pxmitpriv->xmit_tasklet,
42 (void(*)(unsigned long))rtl8192cu_xmit_tasklet,
43 (unsigned long)padapter);
48 void rtl8192cu_free_xmit_priv(_adapter *padapter)
52 static void do_queue_select(_adapter *padapter, struct pkt_attrib *pattrib)
56 qsel = pattrib->priority;
57 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("### do_queue_select priority=%d ,qsel = %d\n",pattrib->priority ,qsel));
59 #ifdef CONFIG_CONCURRENT_MODE
60 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
67 int urb_zero_packet_chk(_adapter *padapter, int sz)
69 int blnSetTxDescOffset;
70 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
72 if ( pdvobj->ishighspeed )
74 if ( ( (sz + TXDESC_SIZE) % 512 ) == 0 ) {
75 blnSetTxDescOffset = 1;
77 blnSetTxDescOffset = 0;
82 if ( ( (sz + TXDESC_SIZE) % 64 ) == 0 ) {
83 blnSetTxDescOffset = 1;
85 blnSetTxDescOffset = 0;
89 return blnSetTxDescOffset;
93 void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
95 u16 *usPtr = (u16*)ptxdesc;
96 u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times
101 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
103 for(index = 0 ; index < count ; index++){
104 checksum = checksum ^ le16_to_cpu(*(usPtr + index));
107 ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum);
111 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
113 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
115 switch (pattrib->encrypt)
120 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
124 //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
125 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
128 ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
140 void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
142 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
144 switch(pattrib->vcs_mode)
147 *pdw |= cpu_to_le32(BIT(12));
150 *pdw |= cpu_to_le32(BIT(11));
157 if(pattrib->vcs_mode) {
158 *pdw |= cpu_to_le32(BIT(13));
163 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(27)):0;
165 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
166 *pdw |= cpu_to_le32((0x01<<28)&0x30000000);
167 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
168 *pdw |= cpu_to_le32((0x02<<28)&0x30000000);
169 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
172 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
177 void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
179 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
183 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(25)):0;
185 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
186 *pdw |= cpu_to_le32((0x01<<20)&0x003f0000);
187 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
188 *pdw |= cpu_to_le32((0x02<<20)&0x003f0000);
189 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
192 *pdw |= cpu_to_le32((0x03<<20)&0x003f0000);
196 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
200 _adapter *padapter = pxmitframe->padapter;
201 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
202 struct pkt_attrib *pattrib = &pxmitframe->attrib;
203 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
204 struct dm_priv *pdmpriv = &pHalData->dmpriv;
205 struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
206 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
207 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
208 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
209 sint bmcst = IS_MCAST(pattrib->ra);
211 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
214 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
215 if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
217 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
219 pxmitframe->pkt_offset --;
221 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
223 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
225 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
227 //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");
230 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
232 qsel = (uint)(pattrib->qsel & 0x0000001f);
233 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
235 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
237 fill_txdesc_sectype(pattrib, ptxdesc);
239 if(pattrib->ampdu_en==_TRUE)
240 ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN
242 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
248 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
251 //offset 16 , offset 20
253 ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS
255 if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1))
257 //Non EAP & ARP & DHCP type data packet
259 fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
260 fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
262 ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M
263 ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);//
264 //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M
266 //use REG_INIDATA_RATE_SEL value
267 ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);
269 if(0)//for driver dbg
271 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
274 ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI
276 ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7
282 // EAP data packet and ARP packet.
283 // Use the 1M data rate to send the EAP/ARP packet.
284 // This will maybe make the handshake smooth.
286 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
288 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
290 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
291 ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT
293 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
297 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
298 if ( pattrib->hw_tcp_csum == 1 ) {
299 // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!!
300 u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8;
301 ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16);
302 DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7);
306 else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
308 //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");
311 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
313 qsel = (uint)(pattrib->qsel&0x0000001f);
314 ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);
316 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
318 //fill_txdesc_sectype(pattrib, ptxdesc);
321 #ifdef CONFIG_XMIT_ACK
322 //CCX-TXRPT ack for xmit mgmt frames.
323 if (pxmitframe->ack_report) {
325 static u16 ccx_sw = 0x123;
326 ptxdesc->txdw7 |= cpu_to_le32((((ccx_sw>>8)&0x0f)<<16) | (((ccx_sw>>4)&0x0f)<<28) | (((ccx_sw)&0x0f)<<24));
327 DBG_871X("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
328 ccx_sw = (ccx_sw+1)%0xfff;
330 ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
332 #endif //CONFIG_XMIT_ACK
335 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
338 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
341 ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable
342 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6
344 #ifdef CONFIG_INTEL_PROXIM
345 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
346 DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
347 ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate);
352 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
355 else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
357 DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
359 #ifdef CONFIG_MP_INCLUDED
360 else if(((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) &&
361 (padapter->registrypriv.mp_mode == 1))
363 fill_txdesc_for_mp(padapter, ptxdesc);
368 DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
371 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID)
373 ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid
378 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
381 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
384 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
387 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
388 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
389 // mgnt frame should be controled by Hw because Fw will also send null data
390 // which we cannot control when Fw LPS enable.
391 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
392 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
393 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
394 // 2010.06.23. Added by tynli.
397 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
398 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
402 ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
403 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
404 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc
408 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
411 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0));
414 // pkt_offset, unit:8 bytes padding
415 if (pxmitframe->pkt_offset > 0)
416 ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
418 #ifdef CONFIG_USB_TX_AGGREGATION
419 if (pxmitframe->agg_num > 1)
420 ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000);
423 rtl8192cu_cal_txdesc_chksum(ptxdesc);
429 #ifdef CONFIG_XMIT_THREAD_MODE
432 * Transmit xmitbuf to hardware tx fifo
436 * _FAIL something error
438 s32 rtl8723au_xmit_buf_handler(PADAPTER padapter)
440 //PHAL_DATA_TYPE phal;
441 struct xmit_priv *pxmitpriv;
442 struct xmit_buf *pxmitbuf;
446 //phal = GET_HAL_DATA(padapter);
447 pxmitpriv = &padapter->xmitpriv;
449 ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
451 RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
452 ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
456 ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
458 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
459 ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
460 __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
464 if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
467 #ifdef CONFIG_LPS_LCLK
468 ret = rtw_register_tx_alive(padapter);
469 if (ret != _SUCCESS) {
470 RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
471 ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
477 pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
478 if (pxmitbuf == NULL) break;
480 rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);
484 #ifdef CONFIG_LPS_LCLK
485 rtw_unregister_tx_alive(padapter);
493 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
496 s32 inner_ret = _SUCCESS;
497 int t, sz, w_sz, pull=0;
500 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
501 struct pkt_attrib *pattrib = &pxmitframe->attrib;
502 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
503 struct security_priv *psecuritypriv = &padapter->securitypriv;
505 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
506 (pxmitframe->attrib.ether_type != 0x0806) &&
507 (pxmitframe->attrib.ether_type != 0x888e) &&
508 (pxmitframe->attrib.dhcp_pkt != 1))
510 rtw_issue_addbareq_cmd(padapter, pxmitframe);
513 mem_addr = pxmitframe->buf_addr;
515 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
517 for (t = 0; t < pattrib->nr_frags; t++)
519 if (inner_ret != _SUCCESS && ret == _SUCCESS)
522 if (t != (pattrib->nr_frags - 1))
524 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
526 sz = pxmitpriv->frag_len;
527 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
531 sz = pattrib->last_txcmdsz;
534 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
538 mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
540 //pxmitbuf ->pbuf = mem_addr;
541 pxmitframe->buf_addr = mem_addr;
543 w_sz = sz + TXDESC_SIZE;
547 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
550 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
551 #ifdef CONFIG_XMIT_THREAD_MODE
552 pxmitbuf->len = w_sz;
553 pxmitbuf->ff_hwaddr = ff_hwaddr;
554 enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
556 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
558 rtw_count_tx_stats(padapter, pxmitframe, sz);
561 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
562 //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);
566 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
570 rtw_free_xmitframe(pxmitpriv, pxmitframe);
573 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
578 #ifdef CONFIG_USB_TX_AGGREGATION
579 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
581 struct pkt_attrib *pattrib = &pxmitframe->attrib;
585 // no consider fragement
586 len = pattrib->hdrlen + pattrib->iv_len +
587 SNAP_SIZE + sizeof(u16) +
589 ((pattrib->bswenc) ? pattrib->icv_len : 0);
591 if(pattrib->encrypt ==_TKIP_)
597 #define IDEA_CONDITION 1 // check all packets before enqueue
598 s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
600 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
601 struct xmit_frame *pxmitframe = NULL;
602 struct xmit_frame *pfirstframe = NULL;
604 // aggregate variable
605 struct hw_xmit *phwxmit;
606 struct sta_info *psta = NULL;
607 struct tx_servq *ptxservq = NULL;
610 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
612 u32 pbuf; // next pkt address
613 u32 pbuf_tail; // last pkt tail
614 u32 len; // packet length, except TXDESC_SIZE and PKT_OFFSET
616 u32 bulkSize = pHalData->UsbBulkOutSize;
620 // dump frame variable
623 #ifndef IDEA_CONDITION
627 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
630 // check xmitbuffer is ok
631 if (pxmitbuf == NULL) {
632 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
633 if (pxmitbuf == NULL) return _FALSE;
637 //3 1. pick up first frame
639 rtw_free_xmitframe(pxmitpriv, pxmitframe);
641 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
642 if (pxmitframe == NULL) {
643 // no more xmit frame, release xmit buffer
644 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
649 #ifndef IDEA_CONDITION
650 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
651 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
652 ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
653 pxmitframe->frame_tag, DATA_FRAMETAG));
654 // rtw_free_xmitframe(pxmitpriv, pxmitframe);
659 if ((pxmitframe->attrib.priority < 0) ||
660 (pxmitframe->attrib.priority > 15)) {
661 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
662 ("xmitframe_complete: TID(%d) should be 0~15!\n",
663 pxmitframe->attrib.priority));
664 // rtw_free_xmitframe(pxmitpriv, pxmitframe);
669 pxmitframe->pxmitbuf = pxmitbuf;
670 pxmitframe->buf_addr = pxmitbuf->pbuf;
671 pxmitbuf->priv_data = pxmitframe;
673 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
674 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
676 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
677 DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
682 // always return ndis_packet after rtw_xmitframe_coalesce
683 rtw_os_xmit_complete(padapter, pxmitframe);
688 //3 2. aggregate same priority and same DA(AP or STA) frames
689 pfirstframe = pxmitframe;
690 len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
692 pbuf = _RND8(pbuf_tail);
694 // check pkt amount in one bluk
701 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
704 // dequeue same priority packet from station tx queue
705 psta = pfirstframe->attrib.psta;
706 switch (pfirstframe->attrib.priority) {
709 ptxservq = &(psta->sta_xmitpriv.bk_q);
710 phwxmit = pxmitpriv->hwxmits + 3;
715 ptxservq = &(psta->sta_xmitpriv.vi_q);
716 phwxmit = pxmitpriv->hwxmits + 1;
721 ptxservq = &(psta->sta_xmitpriv.vo_q);
722 phwxmit = pxmitpriv->hwxmits;
728 ptxservq = &(psta->sta_xmitpriv.be_q);
729 phwxmit = pxmitpriv->hwxmits + 2;
733 _enter_critical_bh(&pxmitpriv->lock, &irqL);
735 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
736 xmitframe_plist = get_next(xmitframe_phead);
737 while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE)
739 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
740 xmitframe_plist = get_next(xmitframe_plist);
742 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
743 if (pbuf + len > MAX_XMITBUF_SZ) break;
745 rtw_list_delete(&pxmitframe->list);
749 #ifndef IDEA_CONDITION
750 // suppose only data frames would be in queue
751 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
752 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
753 ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
754 pxmitframe->frame_tag, DATA_FRAMETAG));
755 rtw_free_xmitframe(pxmitpriv, pxmitframe);
760 if ((pxmitframe->attrib.priority < 0) ||
761 (pxmitframe->attrib.priority > 15)) {
762 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
763 ("xmitframe_complete: TID(%d) should be 0~15!\n",
764 pxmitframe->attrib.priority));
765 rtw_free_xmitframe(pxmitpriv, pxmitframe);
770 // pxmitframe->pxmitbuf = pxmitbuf;
771 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
773 pxmitframe->agg_num = 0; // not first frame of aggregation
774 pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset
776 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
777 DBG_871X("%s coalesce failed \n",__FUNCTION__);
778 rtw_free_xmitframe(pxmitpriv, pxmitframe);
783 // always return ndis_packet after rtw_xmitframe_coalesce
784 rtw_os_xmit_complete(padapter, pxmitframe);
786 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
787 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
789 // don't need xmitframe any more
790 rtw_free_xmitframe(pxmitpriv, pxmitframe);
792 // handle pointer and stop condition
793 pbuf_tail = pbuf + len;
794 pbuf = _RND8(pbuf_tail);
796 pfirstframe->agg_num++;
797 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
800 if (pbuf < bulkPtr) {
802 if (descCount == pHalData->UsbTxAggDescNum)
806 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
809 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
810 rtw_list_delete(&ptxservq->tx_pending);
812 _exit_critical_bh(&pxmitpriv->lock, &irqL);
814 if ((pfirstframe->attrib.ether_type != 0x0806) &&
815 (pfirstframe->attrib.ether_type != 0x888e) &&
816 (pfirstframe->attrib.dhcp_pkt != 1))
818 rtw_issue_addbareq_cmd(padapter, pfirstframe);
821 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
822 //3 3. update first frame txdesc
823 if ((pbuf_tail % bulkSize) == 0) {
825 pbuf_tail -= PACKET_OFFSET_SZ;
826 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
827 pfirstframe->pkt_offset = 0;
829 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
830 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
832 //3 4. write xmit buffer to USB FIFO
833 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
835 // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
836 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
839 //3 5. update statisitc
840 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
841 if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
843 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
845 rtw_free_xmitframe(pxmitpriv, pfirstframe);
852 s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
855 struct hw_xmit *phwxmits;
857 struct xmit_frame *pxmitframe=NULL;
858 int res=_SUCCESS, xcnt = 0;
860 phwxmits = pxmitpriv->hwxmits;
861 hwentry = pxmitpriv->hwxmit_entry;
863 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
867 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
877 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
881 pxmitframe->pxmitbuf = pxmitbuf;
883 pxmitframe->buf_addr = pxmitbuf->pbuf;
885 pxmitbuf->priv_data = pxmitframe;
887 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
889 if(pxmitframe->attrib.priority<=15)//TID0~15
891 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
894 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
898 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
903 rtw_dump_xframe(padapter, pxmitframe);
907 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
908 rtw_free_xmitframe(pxmitpriv, pxmitframe);
916 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
922 }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
931 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
936 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
937 if (res == _SUCCESS) {
938 rtw_dump_xframe(padapter, pxmitframe);
946 * _TRUE dump packet directly
947 * _FALSE enqueue packet
949 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
953 struct xmit_buf *pxmitbuf = NULL;
954 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
955 struct pkt_attrib *pattrib = &pxmitframe->attrib;
956 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
958 struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);
959 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
960 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
962 #ifdef CONFIG_CONCURRENT_MODE
963 PADAPTER pbuddy_adapter = padapter->pbuddy_adapter;
964 struct mlme_priv *pbuddy_mlmepriv = &(pbuddy_adapter->mlmepriv);
967 do_queue_select(padapter, pattrib);
969 _enter_critical_bh(&pxmitpriv->lock, &irqL);
972 #ifdef CONFIG_AP_MODE
973 if(xmitframe_enqueue_for_sleeping_sta(padapter, pxmitframe) == _TRUE)
975 struct sta_info *psta;
976 struct sta_priv *pstapriv = &padapter->stapriv;
979 _exit_critical_bh(&pxmitpriv->lock, &irqL);
983 psta = pattrib->psta;
987 psta=rtw_get_stainfo(pstapriv, pattrib->ra);
992 if(psta->sleepq_len > (NR_XMITFRAME>>3))
994 wakeup_sta_to_xmit(padapter, psta);
1001 //else CONFIG_TDLS, process as TDLS Buffer STA
1003 if(pmlmeinfo->tdls_setup_state&TDLS_LINKED_STATE ){ //&& pattrib->ether_type!=0x0806)
1004 res = xmit_tdls_enqueue_for_sleeping_sta(padapter, pxmitframe);
1006 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1014 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
1017 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1020 #ifdef CONFIG_CONCURRENT_MODE
1021 if (check_fwstate(pbuddy_mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1025 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1026 if (pxmitbuf == NULL)
1029 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1031 pxmitframe->pxmitbuf = pxmitbuf;
1032 pxmitframe->buf_addr = pxmitbuf->pbuf;
1033 pxmitbuf->priv_data = pxmitframe;
1035 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
1036 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1037 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1043 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
1044 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1046 if (res != _SUCCESS) {
1047 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
1048 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1050 // Trick, make the statistics correct
1051 pxmitpriv->tx_pkts--;
1052 pxmitpriv->tx_drop++;
1059 s32 rtl8192cu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
1061 return rtw_dump_xframe(padapter, pmgntframe);
1066 * _TRUE dump packet directly ok
1067 * _FALSE temporary can't transmit packets to hardware
1069 s32 rtl8192cu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
1071 return pre_xmitframe(padapter, pxmitframe);
1074 s32 rtl8723au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
1076 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1079 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
1081 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1083 // Trick, make the statistics correct
1084 pxmitpriv->tx_pkts--;
1085 pxmitpriv->tx_drop++;
1089 #ifdef PLATFORM_LINUX
1090 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1099 #ifdef CONFIG_HOSTAPD_MLME
1101 static void rtl8192cu_hostap_mgnt_xmit_cb(struct urb *urb)
1103 #ifdef PLATFORM_LINUX
1104 struct sk_buff *skb = (struct sk_buff *)urb->context;
1106 //DBG_8192C("%s\n", __FUNCTION__);
1112 s32 rtl8192cu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1114 #ifdef PLATFORM_LINUX
1117 unsigned int bmcst, tid, qsel;
1118 struct sk_buff *skb, *pxmit_skb;
1120 unsigned char *pxmitbuf;
1121 struct tx_desc *ptxdesc;
1122 struct ieee80211_hdr *tx_hdr;
1123 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
1124 struct net_device *pnetdev = padapter->pnetdev;
1125 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1126 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
1129 //DBG_8192C("%s\n", __FUNCTION__);
1134 tx_hdr = (struct ieee80211_hdr *)(skb->data);
1135 fc = le16_to_cpu(tx_hdr->frame_ctl);
1136 bmcst = IS_MCAST(tx_hdr->addr1);
1138 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_MGMT)
1141 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
1146 pxmitbuf = pxmit_skb->data;
1148 urb = usb_alloc_urb(0, GFP_ATOMIC);
1153 // ----- fill tx desc -----
1154 ptxdesc = (struct tx_desc *)pxmitbuf;
1155 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1158 ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff);
1159 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
1160 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1164 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1168 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
1170 ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
1172 ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
1177 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
1180 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
1186 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
1187 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
1190 rtl8192cu_cal_txdesc_chksum(ptxdesc);
1191 // ----- end of fill tx desc -----
1194 skb_put(pxmit_skb, len + TXDESC_SIZE);
1195 pxmitbuf = pxmitbuf + TXDESC_SIZE;
1196 _rtw_memcpy(pxmitbuf, skb->data, len);
1198 //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
1201 // ----- prepare urb for submit -----
1203 //translate DMA FIFO addr to pipehandle
1204 //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
1205 pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
1207 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
1208 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
1210 urb->transfer_flags |= URB_ZERO_PACKET;
1211 usb_anchor_urb(urb, &phostapdpriv->anchored);
1212 rc = usb_submit_urb(urb, GFP_ATOMIC);
1214 usb_unanchor_urb(urb);