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 <rtl8192d_hal.h>
31 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
32 #error "Shall be Linux or Windows, but not both!\n"
36 s32 rtl8192du_init_xmit_priv(_adapter *padapter)
38 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
41 tasklet_init(&pxmitpriv->xmit_tasklet,
42 (void(*)(unsigned long))rtl8192du_xmit_tasklet,
43 (unsigned long)padapter);
45 #ifdef PLATFORM_FREEBSD
46 TASK_INIT(&pxmitpriv->xmit_tasklet, 1, (task_fn_t *)rtl8192du_xmit_tasklet, (void *)padapter);
52 void rtl8192du_free_xmit_priv(_adapter *padapter)
56 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe);
57 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
60 struct pkt_attrib *pattrib = &pxmitframe->attrib;
83 case 0x11://BC/MC in PS (HIQ)
84 addr = HIGH_QUEUE_INX;
99 int urb_zero_packet_chk(_adapter *padapter, int sz);
100 int urb_zero_packet_chk(_adapter *padapter, int sz)
102 int blnSetTxDescOffset;
103 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
105 if ( pdvobj->ishighspeed )
107 if ( ( (sz + TXDESC_SIZE) % 512 ) == 0 ) {
108 blnSetTxDescOffset = 1;
110 blnSetTxDescOffset = 0;
115 if ( ( (sz + TXDESC_SIZE) % 64 ) == 0 ) {
116 blnSetTxDescOffset = 1;
118 blnSetTxDescOffset = 0;
122 return blnSetTxDescOffset;
126 void rtl8192du_cal_txdesc_chksum(struct tx_desc *ptxdesc)
128 u16 *usPtr = (u16*)ptxdesc;
129 u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times
134 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
136 for(index = 0 ; index < count ; index++){
137 checksum = checksum ^ le16_to_cpu(*(usPtr + index));
140 ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum);
144 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc);
145 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
147 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
149 switch (pattrib->encrypt)
154 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
158 //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
159 ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
162 ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
174 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
176 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
178 switch(pattrib->vcs_mode)
181 *pdw |= cpu_to_le32(BIT(12));
184 *pdw |= cpu_to_le32(BIT(11));
191 if(pattrib->vcs_mode) {
192 *pdw |= cpu_to_le32(BIT(13));
197 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(27)):0;
199 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
200 *pdw |= cpu_to_le32((0x01<<28)&0x30000000);
201 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
202 *pdw |= cpu_to_le32((0x02<<28)&0x30000000);
203 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
206 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
211 static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
213 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
217 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)? cpu_to_le32(BIT(25)):0;
219 if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
220 *pdw |= cpu_to_le32((0x01<<20)&0x00300000);
221 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
222 *pdw |= cpu_to_le32((0x02<<20)&0x00300000);
223 else if(pattrib->ch_offset == HAL_PRIME_CHNL_OFFSET_DONT_CARE)
226 *pdw |= cpu_to_le32((0x03<<20)&0x00300000);
231 Insert Early mode 's Content,8Byte
237 InsertEMContent(IN struct xmit_frame *pxmitframe, IN u8 *VirtualAddress);
239 InsertEMContent(IN struct xmit_frame *pxmitframe, IN u8 *VirtualAddress)
241 _rtw_memset(VirtualAddress, 0, 8);
242 SET_EARLYMODE_PKTNUM(VirtualAddress, pxmitframe->EMPktNum);
243 SET_EARLYMODE_LEN0(VirtualAddress, pxmitframe->EMPktLen[0]);
244 SET_EARLYMODE_LEN1(VirtualAddress, pxmitframe->EMPktLen[1]);
245 SET_EARLYMODE_LEN2_1(VirtualAddress, pxmitframe->EMPktLen[2]&0xF);
246 SET_EARLYMODE_LEN2_2(VirtualAddress, pxmitframe->EMPktLen[2]>>4);
247 SET_EARLYMODE_LEN3(VirtualAddress, pxmitframe->EMPktLen[3]);
248 SET_EARLYMODE_LEN4(VirtualAddress, pxmitframe->EMPktLen[4]);
249 //RT_PRINT_DATA(COMP_SEND, DBG_LOUD, "EM Header:", VirtualAddress, 8)
252 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
256 _adapter *padapter = pxmitframe->padapter;
257 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
258 struct dm_priv *pdmpriv = &pHalData->dmpriv;
259 #ifdef CONFIG_AP_MODE
260 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
261 #endif //CONFIG_AP_MODE
262 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
263 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
264 struct pkt_attrib *pattrib = &pxmitframe->attrib;
265 struct tx_desc *ptxdesc = (struct tx_desc *)pmem;
266 sint bmcst = IS_MCAST(pattrib->ra);
268 struct wifidirect_info *pwdinfo = &padapter->wdinfo;
269 struct registry_priv *pregistrypriv = &padapter->registrypriv;
273 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
274 if (padapter->registrypriv.mp_mode == 0)
277 if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
279 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
281 pxmitframe->pkt_offset --;
284 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
286 _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
288 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
290 //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");
293 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
295 qsel = (uint)(pattrib->qsel & 0x0000001f);
296 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
298 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
300 fill_txdesc_sectype(pattrib, ptxdesc);
302 if(pattrib->ampdu_en==_TRUE){
303 ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN
304 //Insert Early Mode Content after tx desc position.
305 if((pHalData->bEarlyModeEnable) && (_TRUE == bagg_pkt)){
306 ptxdesc->txdw0 |= cpu_to_le32(((USB_HWDESC_HEADER_LEN-8) << OFFSET_SHT) & 0x00ff0000);//32 bytes for TX Desc
307 if(pxmitframe->EMPktNum > 0){
308 InsertEMContent(pxmitframe, pmem+TXDESC_SIZE);
314 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
321 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
324 //offset 16 , offset 20
326 ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS
328 if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1))
330 //Non EAP & ARP & DHCP type data packet
332 fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
333 fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
335 ptxdesc->txdw4 |= cpu_to_le32(0x00000008);//RTS Rate=24M
336 ptxdesc->txdw5 |= cpu_to_le32(0x0001ff00);//
337 //ptxdesc->txdw5 |= cpu_to_le32(0x0000000b);//DataRate - 54M
339 //use REG_INIDATA_RATE_SEL value
340 ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);
342 if(0)//for driver dbg
344 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
347 ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI
349 ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7
355 // EAP data packet and ARP packet.
356 // Use the 1M data rate to send the EAP/ARP packet.
357 // This will maybe make the handshake smooth.
359 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
361 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
363 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
364 ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT
366 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
370 if(pregistrypriv->wifi_spec==1 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
372 ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
374 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
376 ptxdesc->txdw5 = cpu_to_le32(0x0001ff00);//
378 ptxdesc->txdw5 |= cpu_to_le32(BIT(2));// use OFDM 6Mbps
383 #ifdef CONFIG_TCP_CSUM_OFFLOAD_TX
384 if ( pattrib->hw_tcp_csum == 1 ) {
385 // ptxdesc->txdw6 = 0; // clear TCP_CHECKSUM and IP_CHECKSUM. It's zero already!!
386 u8 ip_hdr_offset = 32 + pattrib->hdrlen + pattrib->iv_len + 8;
387 ptxdesc->txdw7 = (1 << 31) | (ip_hdr_offset << 16);
388 DBG_8192C("ptxdesc->txdw7 = %08x\n", ptxdesc->txdw7);
392 else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
394 //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");
397 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
399 qsel = (uint)(pattrib->qsel&0x0000001f);
400 ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);
402 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
404 //fill_txdesc_sectype(pattrib, ptxdesc);
407 #ifdef CONFIG_XMIT_ACK
408 //CCX-TXRPT ack for xmit mgmt frames.
409 if (pxmitframe->ack_report) {
410 ptxdesc->txdw2 |= cpu_to_le32(BIT(19));
412 DBG_871X("%s set ccx\n", __func__);
415 #endif //CONFIG_XMIT_ACK
418 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
421 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
424 #ifdef CONFIG_AP_MODE
425 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
427 ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable
429 if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
431 ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2
435 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6
439 #ifdef CONFIG_INTEL_PROXIM
440 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
441 printk("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
442 ptxdesc->txdw5 |= cpu_to_le32( pattrib->rate);
447 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
450 else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
452 DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
454 #ifdef CONFIG_MP_INCLUDED
455 else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG)
457 fill_txdesc_for_mp(padapter, ptxdesc);
462 DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
465 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID)
467 ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid
472 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
475 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
478 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
481 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
482 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
483 // mgnt frame should be controled by Hw because Fw will also send null data
484 // which we cannot control when Fw LPS enable.
485 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
486 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
487 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
488 // 2010.06.23. Added by tynli.
491 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
492 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
496 ptxdesc->txdw0 |= cpu_to_le32(sz&0x0000ffff);
497 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
498 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//32 bytes for TX Desc
502 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
505 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0));
508 // pkt_offset, unit:8 bytes padding
509 if (pxmitframe->pkt_offset > 0)
510 ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
512 #ifdef CONFIG_USB_TX_AGGREGATION
513 if (pxmitframe->agg_num > 1)
514 ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000);
517 rtl8192du_cal_txdesc_chksum(ptxdesc);
523 s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
526 s32 inner_ret = _SUCCESS;
527 int t, sz, w_sz, pull=0;
530 struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
531 struct pkt_attrib *pattrib = &pxmitframe->attrib;
532 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
533 struct security_priv *psecuritypriv = &padapter->securitypriv;
535 struct sta_priv *pstapriv = &padapter->stapriv;
536 struct sta_info *ptdls_sta=NULL, *psta_backup=NULL;
540 if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
541 (pxmitframe->attrib.ether_type != 0x0806) &&
542 (pxmitframe->attrib.ether_type != 0x888e) &&
543 (pxmitframe->attrib.dhcp_pkt != 1))
546 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
547 if((ptdls_sta!=NULL)&&(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
549 psta_backup = pattrib->psta;
550 pattrib->psta = ptdls_sta;
551 _rtw_memcpy(ra_backup, pattrib->ra, ETH_ALEN);
552 _rtw_memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
553 rtw_issue_addbareq_cmd(padapter, pxmitframe);
554 pattrib->psta = psta_backup;
555 _rtw_memcpy(pattrib->ra, ra_backup, ETH_ALEN);
558 rtw_issue_addbareq_cmd(padapter, pxmitframe);
561 mem_addr = pxmitframe->buf_addr;
563 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
565 for (t = 0; t < pattrib->nr_frags; t++)
567 if (inner_ret != _SUCCESS && ret == _SUCCESS)
570 if (t != (pattrib->nr_frags - 1))
572 RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
574 sz = pxmitpriv->frag_len;
575 sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
579 sz = pattrib->last_txcmdsz;
582 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
586 mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
588 //pxmitbuf ->pbuf = mem_addr;
589 pxmitframe->buf_addr = mem_addr;
591 w_sz = sz + TXDESC_SIZE;
595 w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
598 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
600 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
602 rtw_count_tx_stats(padapter, pxmitframe, sz);
605 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
606 //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);
610 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
614 rtw_free_xmitframe(pxmitpriv, pxmitframe);
617 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
623 #ifdef CONFIG_USB_TX_AGGREGATION
624 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
626 struct pkt_attrib *pattrib = &pxmitframe->attrib;
630 // no consider fragement
631 len = pattrib->hdrlen + pattrib->iv_len +
632 SNAP_SIZE + sizeof(u16) +
634 ((pattrib->bswenc) ? pattrib->icv_len : 0);
636 if(pattrib->encrypt ==_TKIP_)
642 void UpdateEarlyModeInfo8192D(_adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq);
643 void UpdateEarlyModeInfo8192D(_adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq)
647 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
648 struct pkt_attrib *pattrib = &pxmitframe->attrib;
649 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
651 //Some macaddr can't do early mode.
652 if(MacAddr_isBcst(pattrib->dst) ||IS_MCAST(pattrib->dst) || !!pattrib->qos_en)
655 pxmitframe->EMPktNum = 0;
657 // dequeue same priority packet from station tx queue
658 _enter_critical_bh(&pxmitpriv->lock, &irqL);
660 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
661 xmitframe_plist = get_next(xmitframe_phead);
662 while ((rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE)&&(pxmitframe->EMPktNum < 5))
664 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
665 xmitframe_plist = get_next(xmitframe_plist);
667 len = xmitframe_need_length(pxmitframe);
668 pxmitframe->EMPktLen[pxmitframe->EMPktNum] = len;
669 pxmitframe->EMPktNum++;
671 _exit_critical_bh(&pxmitpriv->lock, &irqL);
675 #define IDEA_CONDITION 1 // check all packets before enqueue
676 s32 rtl8192du_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
678 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
679 struct xmit_frame *pxmitframe = NULL;
680 struct xmit_frame *pfirstframe = NULL;
682 // aggregate variable
683 struct hw_xmit *phwxmit = pxmitpriv->hwxmits;
684 struct tx_servq *ptxservq = NULL;
687 _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
689 u32 pbuf=0; // next pkt address
690 u32 pbuf_tail; // last pkt tail
691 u32 len=0; //packet length, except TXDESC_SIZE and PKT_OFFSET
692 u32 aggMaxLength = MAX_XMITBUF_SZ;
693 u32 bulkSize = pHalData->UsbBulkOutSize;
697 u8 bfirst = _TRUE;//first aggregation xmitframe
698 u8 bulkstart = _FALSE;
700 // dump frame variable
703 #ifndef IDEA_CONDITION
707 RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
709 // check xmitbuffer is ok
710 if (pxmitbuf == NULL) {
711 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
712 if (pxmitbuf == NULL) return _FALSE;
715 if(pHalData->MacPhyMode92D==SINGLEMAC_SINGLEPHY)
716 aggMaxLength = MAX_XMITBUF_SZ;
718 aggMaxLength = 0x3D00;
721 //3 1. pick up first frame
724 pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
725 if (pxmitframe == NULL) {
726 // no more xmit frame, release xmit buffer
727 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
731 pxmitframe->pxmitbuf = pxmitbuf;
732 pxmitframe->buf_addr = pxmitbuf->pbuf;
733 pxmitbuf->priv_data = pxmitframe;
735 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
736 pxmitframe->pkt_offset = USB_92D_DUMMY_OFFSET; // first frame of aggregation, reserve 2 offset for 512 alignment and early mode
738 pfirstframe = pxmitframe;
739 _enter_critical_bh(&pxmitpriv->lock, &irqL);
740 ptxservq = rtw_get_sta_pending(padapter, pfirstframe->attrib.psta, pfirstframe->attrib.priority, (u8 *)(&ac_index));
741 _exit_critical_bh(&pxmitpriv->lock, &irqL);
743 //3 2. aggregate same priority and same DA(AP or STA) frames
746 // dequeue same priority packet from station tx queue
747 _enter_critical_bh(&pxmitpriv->lock, &irqL);
749 if (_rtw_queue_empty(&ptxservq->sta_pending) == _FALSE)
751 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
752 xmitframe_plist = get_next(xmitframe_phead);
754 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
757 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + ((USB_92D_DUMMY_OFFSET - 1) * PACKET_OFFSET_SZ);
758 if (pbuf + _RND8(len) > aggMaxLength)
764 rtw_list_delete(&pxmitframe->list);
766 phwxmit[ac_index].accnt--;
768 //Remove sta node when there is no pending packets.
769 if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
770 rtw_list_delete(&ptxservq->tx_pending);
778 _exit_critical_bh(&pxmitpriv->lock, &irqL);
785 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
787 pxmitframe->agg_num = 0; // not first frame of aggregation
788 pxmitframe->pkt_offset = USB_92D_DUMMY_OFFSET - 1; // not first frame of aggregation, reserve 1 offset for early mode
791 if(pHalData->bEarlyModeEnable)
792 UpdateEarlyModeInfo8192D(padapter, pxmitframe,ptxservq);
795 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
796 DBG_871X("%s coalesce failed \n",__FUNCTION__);
797 rtw_free_xmitframe(pxmitpriv, pxmitframe);
802 // always return ndis_packet after rtw_xmitframe_coalesce
803 rtw_os_xmit_complete(padapter, pxmitframe);
807 len = xmitframe_need_length(pfirstframe) + USB_HWDESC_HEADER_LEN;
809 pbuf = _RND8(pbuf_tail);
817 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
819 // don't need xmitframe any more
820 rtw_free_xmitframe(pxmitpriv, pxmitframe);
822 // handle pointer and stop condition
823 pbuf_tail = pbuf + len;
824 pbuf = _RND8(pbuf_tail);
826 pfirstframe->agg_num++;
827 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
831 // check pkt amount in one bluk
835 if (descCount == pHalData->UsbTxAggDescNum)
841 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
845 if ((pfirstframe->attrib.ether_type != 0x0806) &&
846 (pfirstframe->attrib.ether_type != 0x888e) &&
847 (pfirstframe->attrib.dhcp_pkt != 1))
849 rtw_issue_addbareq_cmd(padapter, pfirstframe);
852 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
853 //3 3. update first frame txdesc
854 if ((pbuf_tail % bulkSize) == 0) {
855 // remove 1 pkt_offset
856 pbuf_tail -= PACKET_OFFSET_SZ;
857 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
858 pfirstframe->pkt_offset--;
860 #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
861 update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
863 //3 4. write xmit buffer to USB FIFO
864 ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
866 // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
867 rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
869 //3 5. update statisitc
870 pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
871 //if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
872 pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
874 rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
876 rtw_free_xmitframe(pxmitpriv, pfirstframe);
883 s32 rtl8192du_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
886 struct hw_xmit *phwxmits;
888 struct xmit_frame *pxmitframe=NULL;
889 int res=_SUCCESS, xcnt = 0;
891 phwxmits = pxmitpriv->hwxmits;
892 hwentry = pxmitpriv->hwxmit_entry;
894 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
898 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
907 pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
911 pxmitframe->pxmitbuf = pxmitbuf;
913 pxmitframe->buf_addr = pxmitbuf->pbuf;
915 pxmitbuf->priv_data = pxmitframe;
917 if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
919 if(pxmitframe->attrib.priority<=15)//TID0~15
921 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
924 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
928 RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
933 rtw_dump_xframe(padapter, pxmitframe);
937 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
938 rtw_free_xmitframe(pxmitpriv, pxmitframe);
946 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
952 }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
960 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
965 res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
966 if (res == _SUCCESS) {
967 rtw_dump_xframe(padapter, pxmitframe);
975 * _TRUE dump packet directly
976 * _FALSE enqueue packet
978 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
982 struct xmit_buf *pxmitbuf = NULL;
983 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
984 struct pkt_attrib *pattrib = &pxmitframe->attrib;
985 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
987 _enter_critical_bh(&pxmitpriv->lock, &irqL);
989 #ifdef PLATFORM_FREEBSD
990 //force tx to enqueue, and schedule tx task later.
992 #endif // PLATFORM_FREEBSD
994 if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0
995 #ifdef CONFIG_DUALMAC_CONCURRENT
996 || (dc_check_xmit(padapter)== _FALSE)
1003 if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1006 #ifdef CONFIG_CONCURRENT_MODE
1007 if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1009 #endif //CONFIG_CONCURRENT_MODE
1011 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1012 if (pxmitbuf == NULL)
1015 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1017 pxmitframe->pxmitbuf = pxmitbuf;
1018 pxmitframe->buf_addr = pxmitbuf->pbuf;
1019 pxmitbuf->priv_data = pxmitframe;
1021 if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
1022 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1023 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1029 res = rtw_xmitframe_enqueue(padapter, pxmitframe);
1030 _exit_critical_bh(&pxmitpriv->lock, &irqL);
1032 if (res != _SUCCESS) {
1033 RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
1034 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1036 // Trick, make the statistics correct
1037 pxmitpriv->tx_pkts--;
1038 pxmitpriv->tx_drop++;
1042 #ifdef PLATFORM_FREEBSD
1043 rtw_os_xmit_schedule(padapter);
1044 #endif // PLATFORM_FREEBSD
1049 s32 rtl8192du_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
1051 return rtw_dump_xframe(padapter, pmgntframe);
1056 * _TRUE dump packet directly ok
1057 * _FALSE temporary can't transmit packets to hardware
1059 s32 rtl8192du_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
1061 return pre_xmitframe(padapter, pxmitframe);
1064 s32 rtl8192du_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
1066 struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1069 if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
1071 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1073 // Trick, make the statistics correct
1074 pxmitpriv->tx_pkts--;
1075 pxmitpriv->tx_drop++;
1079 #ifdef PLATFORM_LINUX
1080 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1088 #ifdef CONFIG_HOSTAPD_MLME
1090 static void rtl8192du_hostap_mgnt_xmit_cb(struct urb *urb)
1092 #ifdef PLATFORM_LINUX
1093 struct sk_buff *skb = (struct sk_buff *)urb->context;
1095 //DBG_8192C("%s\n", __FUNCTION__);
1101 s32 rtl8192du_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1103 #ifdef PLATFORM_LINUX
1106 unsigned int bmcst, tid, qsel;
1107 struct sk_buff *skb, *pxmit_skb;
1109 unsigned char *pxmitbuf;
1110 struct tx_desc *ptxdesc;
1111 struct rtw_ieee80211_hdr *tx_hdr;
1112 struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
1113 struct net_device *pnetdev = padapter->pnetdev;
1114 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1115 struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
1118 //DBG_8192C("%s\n", __FUNCTION__);
1123 tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
1124 fc = le16_to_cpu(tx_hdr->frame_ctl);
1125 bmcst = IS_MCAST(tx_hdr->addr1);
1127 if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
1130 pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
1135 pxmitbuf = pxmit_skb->data;
1136 #ifdef PLATFORM_FREEBSD
1137 urb = rtw_usb_alloc_urb(0, GFP_ATOMIC);
1138 #else //PLATFORM_FREEBSD
1139 urb = usb_alloc_urb(0, GFP_ATOMIC);
1140 #endif //PLATFORM_FREEBSD
1145 // ----- fill tx desc -----
1146 ptxdesc = (struct tx_desc *)pxmitbuf;
1147 _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1150 ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff);
1151 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
1152 ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
1156 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1160 ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
1162 ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
1164 ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
1169 ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
1172 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
1178 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
1179 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
1182 rtl8192cu_cal_txdesc_chksum(ptxdesc);
1183 // ----- end of fill tx desc -----
1186 skb_put(pxmit_skb, len + TXDESC_SIZE);
1187 pxmitbuf = pxmitbuf + TXDESC_SIZE;
1188 _rtw_memcpy(pxmitbuf, skb->data, len);
1190 //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
1193 // ----- prepare urb for submit -----
1195 //translate DMA FIFO addr to pipehandle
1196 //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
1197 pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
1198 #ifdef PLATFORM_FREEBSD
1199 rtw_usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
1200 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
1201 #else //PLATFORM_FREEBSD
1202 usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
1203 pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
1204 #endif //PLATFORM_FREEBSD
1206 urb->transfer_flags |= URB_ZERO_PACKET;
1207 usb_anchor_urb(urb, &phostapdpriv->anchored);
1208 #ifdef PLATFORM_FREEBSD
1209 rc = rtw_usb_submit_urb(urb, GFP_ATOMIC);
1210 #else //PLATFORM_FREEBSD
1211 rc = usb_submit_urb(urb, GFP_ATOMIC);
1212 #endif //PLATFORM_FREEBSD
1214 usb_unanchor_urb(urb);
1217 #ifdef PLATFORM_FREEBSD
1218 rtw_usb_free_urb(urb);
1219 #else //PLATFORM_FREEBSD
1221 #endif //PLATFORM_FREEBSD