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>
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 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
55 struct pkt_attrib *pattrib = &pxmitframe->attrib;
78 case 0x11://BC/MC in PS (HIQ)
79 addr = HIGH_QUEUE_INX;
94 int urb_zero_packet_chk(_adapter *padapter, int sz)
96 int blnSetTxDescOffset;
97 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
99 if ( pdvobj->ishighspeed )
101 if ( ( (sz + TXDESC_SIZE) % 512 ) == 0 ) {
102 blnSetTxDescOffset = 1;
104 blnSetTxDescOffset = 0;
109 if ( ( (sz + TXDESC_SIZE) % 64 ) == 0 ) {
110 blnSetTxDescOffset = 1;
112 blnSetTxDescOffset = 0;
116 return blnSetTxDescOffset;
120 void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
122 u16 *usPtr = (u16*)ptxdesc;
123 u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times
128 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
130 for(index = 0 ; index < count ; index++){
131 checksum = checksum ^ le16_to_cpu(*(usPtr + index));
134 ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum);
138 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
140 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
142 switch (pattrib->encrypt)
147 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
151 //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
152 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
155 ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
167 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
169 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
171 switch(pattrib->vcs_mode)
174 *pdw |= cpu_to_le32(BIT(12));
177 *pdw |= cpu_to_le32(BIT(11));
184 if(pattrib->vcs_mode) {
185 *pdw |= cpu_to_le32(BIT(13));
190 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(27)):0;
192 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
193 *pdw |= cpu_to_le32((0x01<<28)&0x30000000);
194 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
195 *pdw |= cpu_to_le32((0x02<<28)&0x30000000);
196 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
199 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
204 static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
206 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
210 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(25)):0;
212 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
213 *pdw |= cpu_to_le32((0x01<<20)&0x00300000);
214 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
215 *pdw |= cpu_to_le32((0x02<<20)&0x00300000);
216 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
219 *pdw |= cpu_to_le32((0x03<<20)&0x00300000);
223 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
227 _adapter *padapter = pxmitframe->padapter;
228 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
229 struct pkt_attrib *pattrib = &pxmitframe->attrib;
230 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
231 struct dm_priv *pdmpriv = &pHalData->dmpriv;
232 struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
233 struct ht_priv *phtpriv = &pmlmepriv->htpriv;
234 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
235 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
236 sint bmcst = IS_MCAST(pattrib->ra);
238 struct wifidirect_info* pwdinfo = &padapter->wdinfo;
241 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
242 if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
244 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
246 pxmitframe->pkt_offset --;
248 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
250 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
252 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
254 //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");
257 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
259 qsel = (uint)(pattrib->qsel & 0x0000001f);
260 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
262 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
264 fill_txdesc_sectype(pattrib, ptxdesc);
266 if(pattrib->ampdu_en==_TRUE)
267 ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN
269 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
275 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
278 //offset 16 , offset 20
280 ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS
282 if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1))
284 //Non EAP & ARP & DHCP type data packet
286 fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
287 fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
289 ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M
290 ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);//
291 //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M
293 //use REG_INIDATA_RATE_SEL value
294 ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);
296 if(0)//for driver dbg
298 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
301 ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI
303 ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7
309 // EAP data packet and ARP packet.
310 // Use the 1M data rate to send the EAP/ARP packet.
311 // This will maybe make the handshake smooth.
313 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
315 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
317 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
318 ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT
320 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
324 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
325 if ( pattrib->hw_tcp_csum == 1 ) {
326 // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!!
327 u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8;
328 ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16);
329 DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7);
333 else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
335 //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");
338 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
340 qsel = (uint)(pattrib->qsel&0x0000001f);
341 ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);
343 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
345 //fill_txdesc_sectype(pattrib, ptxdesc);
348 #ifdef CONFIG_XMIT_ACK
349 //CCX-TXRPT ack for xmit mgmt frames.
350 if (pxmitframe->ack_report) {
351 ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
353 DBG_871X("%s set ccx\n", __func__);
356 #endif //CONFIG_XMIT_ACK
359 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
362 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
365 ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable
366 if(pattrib->retry_ctrl == _TRUE)
369 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
371 #ifdef CONFIG_INTEL_WIDI
372 if(padapter->mlmepriv.widi_enable == _TRUE)
373 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6
375 #endif //CONFIG_INTEL_WIDI
376 ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2
380 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6
383 ptxdesc->txdw5 |= cpu_to_le32(0x00300000);//retry limit = 12
385 #ifdef CONFIG_INTEL_PROXIM
386 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
387 printk("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
388 ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate);
393 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
396 else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
398 DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
400 #ifdef CONFIG_MP_INCLUDED
401 else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG)
403 fill_txdesc_for_mp(padapter, ptxdesc);
408 DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
411 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID)
413 ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid
418 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
421 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
424 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
427 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
428 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
429 // mgnt frame should be controled by Hw because Fw will also send null data
430 // which we cannot control when Fw LPS enable.
431 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
432 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
433 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
434 // 2010.06.23. Added by tynli.
437 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
438 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
442 ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
443 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
444 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc
448 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
451 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0));
454 // pkt_offset, unit:8 bytes padding
455 if (pxmitframe->pkt_offset > 0)
456 ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
458 #ifdef CONFIG_USB_TX_AGGREGATION
459 if (pxmitframe->agg_num > 1)
460 ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000);
463 rtl8192cu_cal_txdesc_chksum(ptxdesc);
469 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
472 s32 inner_ret = _SUCCESS;
473 int t, sz, w_sz, pull=0;
476 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
477 struct pkt_attrib *pattrib = &pxmitframe->attrib;
478 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
479 struct security_priv *psecuritypriv = &padapter->securitypriv;
481 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
482 (pxmitframe->attrib.ether_type != 0x0806) &&
483 (pxmitframe->attrib.ether_type != 0x888e) &&
484 (pxmitframe->attrib.dhcp_pkt != 1))
486 rtw_issue_addbareq_cmd(padapter, pxmitframe);
489 mem_addr = pxmitframe->buf_addr;
491 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
493 for (t = 0; t < pattrib->nr_frags; t++)
495 if (inner_ret != _SUCCESS && ret == _SUCCESS)
498 if (t != (pattrib->nr_frags - 1))
500 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
502 sz = pxmitpriv->frag_len;
503 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
507 sz = pattrib->last_txcmdsz;
510 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
514 mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
516 //pxmitbuf ->pbuf = mem_addr;
517 pxmitframe->buf_addr = mem_addr;
519 w_sz = sz + TXDESC_SIZE;
523 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
526 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
528 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
530 rtw_count_tx_stats(padapter, pxmitframe, sz);
533 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
534 //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);
538 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
542 rtw_free_xmitframe(pxmitpriv, pxmitframe);
545 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
550 #ifdef CONFIG_USB_TX_AGGREGATION
551 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
553 struct pkt_attrib *pattrib = &pxmitframe->attrib;
557 // no consider fragement
558 len = pattrib->hdrlen + pattrib->iv_len +
559 SNAP_SIZE + sizeof(u16) +
561 ((pattrib->bswenc) ? pattrib->icv_len : 0);
563 if(pattrib->encrypt ==_TKIP_)
569 #define IDEA_CONDITION 1 // check all packets before enqueue
570 s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
572 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
573 struct xmit_frame *pxmitframe = NULL;
574 struct xmit_frame *pfirstframe = NULL;
576 // aggregate variable
577 struct hw_xmit *phwxmit;
578 struct sta_info *psta = NULL;
579 struct tx_servq *ptxservq = NULL;
582 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
584 u32 pbuf; // next pkt address
585 u32 pbuf_tail; // last pkt tail
586 u32 len; // packet length, except TXDESC_SIZE and PKT_OFFSET
588 u32 bulkSize = pHalData->UsbBulkOutSize;
592 // dump frame variable
595 #ifndef IDEA_CONDITION
599 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
602 // check xmitbuffer is ok
603 if (pxmitbuf == NULL) {
604 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
605 if (pxmitbuf == NULL) return _FALSE;
609 //3 1. pick up first frame
611 rtw_free_xmitframe(pxmitpriv, pxmitframe);
613 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
614 if (pxmitframe == NULL) {
615 // no more xmit frame, release xmit buffer
616 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
621 #ifndef IDEA_CONDITION
622 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
623 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
624 ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
625 pxmitframe->frame_tag, DATA_FRAMETAG));
626 // rtw_free_xmitframe(pxmitpriv, pxmitframe);
631 if ((pxmitframe->attrib.priority < 0) ||
632 (pxmitframe->attrib.priority > 15)) {
633 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
634 ("xmitframe_complete: TID(%d) should be 0~15!\n",
635 pxmitframe->attrib.priority));
636 // rtw_free_xmitframe(pxmitpriv, pxmitframe);
641 pxmitframe->pxmitbuf = pxmitbuf;
642 pxmitframe->buf_addr = pxmitbuf->pbuf;
643 pxmitbuf->priv_data = pxmitframe;
645 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
646 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
649 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
650 DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
655 // always return ndis_packet after rtw_xmitframe_coalesce
656 rtw_os_xmit_complete(padapter, pxmitframe);
661 //3 2. aggregate same priority and same DA(AP or STA) frames
662 pfirstframe = pxmitframe;
663 len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
665 pbuf = _RND8(pbuf_tail);
667 // check pkt amount in one bluk
674 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
677 // dequeue same priority packet from station tx queue
678 psta = pfirstframe->attrib.psta;
679 switch (pfirstframe->attrib.priority) {
682 ptxservq = &(psta->sta_xmitpriv.bk_q);
683 phwxmit = pxmitpriv->hwxmits + 3;
688 ptxservq = &(psta->sta_xmitpriv.vi_q);
689 phwxmit = pxmitpriv->hwxmits + 1;
694 ptxservq = &(psta->sta_xmitpriv.vo_q);
695 phwxmit = pxmitpriv->hwxmits;
701 ptxservq = &(psta->sta_xmitpriv.be_q);
702 phwxmit = pxmitpriv->hwxmits + 2;
706 _enter_critical_bh(&pxmitpriv->lock, &irqL);
708 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
709 xmitframe_plist = get_next(xmitframe_phead);
710 while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE)
712 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
713 xmitframe_plist = get_next(xmitframe_plist);
715 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
716 if (pbuf + len > MAX_XMITBUF_SZ) break;
718 rtw_list_delete(&pxmitframe->list);
722 #ifndef IDEA_CONDITION
723 // suppose only data frames would be in queue
724 if (pxmitframe->frame_tag != DATA_FRAMETAG) {
725 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
726 ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
727 pxmitframe->frame_tag, DATA_FRAMETAG));
728 rtw_free_xmitframe(pxmitpriv, pxmitframe);
733 if ((pxmitframe->attrib.priority < 0) ||
734 (pxmitframe->attrib.priority > 15)) {
735 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
736 ("xmitframe_complete: TID(%d) should be 0~15!\n",
737 pxmitframe->attrib.priority));
738 rtw_free_xmitframe(pxmitpriv, pxmitframe);
743 // pxmitframe->pxmitbuf = pxmitbuf;
744 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
746 pxmitframe->agg_num = 0; // not first frame of aggregation
747 pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset
749 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
750 DBG_871X("%s coalesce failed \n",__FUNCTION__);
751 rtw_free_xmitframe(pxmitpriv, pxmitframe);
755 // always return ndis_packet after rtw_xmitframe_coalesce
756 rtw_os_xmit_complete(padapter, pxmitframe);
758 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
759 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
761 // don't need xmitframe any more
762 rtw_free_xmitframe(pxmitpriv, pxmitframe);
764 // handle pointer and stop condition
765 pbuf_tail = pbuf + len;
766 pbuf = _RND8(pbuf_tail);
768 pfirstframe->agg_num++;
769 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
772 if (pbuf < bulkPtr) {
774 if (descCount == pHalData->UsbTxAggDescNum)
778 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
781 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
782 rtw_list_delete(&ptxservq->tx_pending);
784 _exit_critical_bh(&pxmitpriv->lock, &irqL);
786 if ((pfirstframe->attrib.ether_type != 0x0806) &&
787 (pfirstframe->attrib.ether_type != 0x888e) &&
788 (pfirstframe->attrib.dhcp_pkt != 1))
790 rtw_issue_addbareq_cmd(padapter, pfirstframe);
793 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
794 //3 3. update first frame txdesc
795 if ((pbuf_tail % bulkSize) == 0) {
797 pbuf_tail -= PACKET_OFFSET_SZ;
798 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
799 pfirstframe->pkt_offset = 0;
801 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
802 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
804 //3 4. write xmit buffer to USB FIFO
805 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
807 // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
808 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
811 //3 5. update statisitc
812 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
813 if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
815 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
817 rtw_free_xmitframe(pxmitpriv, pfirstframe);
824 s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
827 struct hw_xmit *phwxmits;
829 struct xmit_frame *pxmitframe=NULL;
830 int res=_SUCCESS, xcnt = 0;
832 phwxmits = pxmitpriv->hwxmits;
833 hwentry = pxmitpriv->hwxmit_entry;
835 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
839 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
849 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
853 pxmitframe->pxmitbuf = pxmitbuf;
855 pxmitframe->buf_addr = pxmitbuf->pbuf;
857 pxmitbuf->priv_data = pxmitframe;
859 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
861 if(pxmitframe->attrib.priority<=15)//TID0~15
863 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
866 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
870 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
875 rtw_dump_xframe(padapter, pxmitframe);
879 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
880 rtw_free_xmitframe(pxmitpriv, pxmitframe);
888 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
894 }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
903 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
908 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
909 if (res == _SUCCESS) {
910 rtw_dump_xframe(padapter, pxmitframe);
918 * _TRUE dump packet directly
919 * _FALSE enqueue packet
921 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
925 struct xmit_buf *pxmitbuf = NULL;
926 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
927 struct pkt_attrib *pattrib = &pxmitframe->attrib;
928 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
931 _enter_critical_bh(&pxmitpriv->lock, &irqL);
934 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
938 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
941 #ifdef CONFIG_CONCURRENT_MODE
942 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
946 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
947 if (pxmitbuf == NULL)
950 _exit_critical_bh(&pxmitpriv->lock, &irqL);
952 pxmitframe->pxmitbuf = pxmitbuf;
953 pxmitframe->buf_addr = pxmitbuf->pbuf;
954 pxmitbuf->priv_data = pxmitframe;
956 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
957 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
958 rtw_free_xmitframe(pxmitpriv, pxmitframe);
964 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
965 _exit_critical_bh(&pxmitpriv->lock, &irqL);
967 if (res != _SUCCESS) {
968 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
969 rtw_free_xmitframe(pxmitpriv, pxmitframe);
971 // Trick, make the statistics correct
972 pxmitpriv->tx_pkts--;
973 pxmitpriv->tx_drop++;
980 s32 rtl8192cu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
982 return rtw_dump_xframe(padapter, pmgntframe);
987 * _TRUE dump packet directly ok
988 * _FALSE temporary can't transmit packets to hardware
990 s32 rtl8192cu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
992 return pre_xmitframe(padapter, pxmitframe);
995 s32 rtl8192cu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
997 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1000 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
1002 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1004 // Trick, make the statistics correct
1005 pxmitpriv->tx_pkts--;
1006 pxmitpriv->tx_drop++;
1010 #ifdef PLATFORM_LINUX
1011 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1019 #ifdef CONFIG_HOSTAPD_MLME
1021 static void rtl8192cu_hostap_mgnt_xmit_cb(struct urb *urb)
1023 #ifdef PLATFORM_LINUX
1024 struct sk_buff *skb = (struct sk_buff *)urb->context;
1026 //DBG_8192C("%s\n", __FUNCTION__);
1032 s32 rtl8192cu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1034 #ifdef PLATFORM_LINUX
1037 unsigned int bmcst, tid, qsel;
1038 struct sk_buff *skb, *pxmit_skb;
1040 unsigned char *pxmitbuf;
1041 struct tx_desc *ptxdesc;
1042 struct rtw_ieee80211_hdr *tx_hdr;
1043 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
1044 struct net_device *pnetdev = padapter->pnetdev;
1045 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1046 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
1049 //DBG_8192C("%s\n", __FUNCTION__);
1054 tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
1055 fc = le16_to_cpu(tx_hdr->frame_ctl);
1056 bmcst = IS_MCAST(tx_hdr->addr1);
1058 if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
1061 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
1066 pxmitbuf = pxmit_skb->data;
1068 urb = usb_alloc_urb(0, GFP_ATOMIC);
1073 // ----- fill tx desc -----
1074 ptxdesc = (struct tx_desc *)pxmitbuf;
1075 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1078 ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff);
1079 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
1080 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1084 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1088 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
1090 ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
1092 ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
1097 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
1100 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
1106 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
1107 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
1110 rtl8192cu_cal_txdesc_chksum(ptxdesc);
1111 // ----- end of fill tx desc -----
1114 skb_put(pxmit_skb, len + TXDESC_SIZE);
1115 pxmitbuf = pxmitbuf + TXDESC_SIZE;
1116 _rtw_memcpy(pxmitbuf, skb->data, len);
1118 //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
1121 // ----- prepare urb for submit -----
1123 //translate DMA FIFO addr to pipehandle
1124 //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
1125 pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
1127 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
1128 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
1130 urb->transfer_flags |= URB_ZERO_PACKET;
1131 usb_anchor_urb(urb, &phostapdpriv->anchored);
1132 rc = usb_submit_urb(urb, GFP_ATOMIC);
1134 usb_unanchor_urb(urb);