add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8192du / hal / rtl8192d / usb / rtl8192du_xmit.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *                                        
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.
8  *
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
12  * more details.
13  *
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
17  *
18  *
19  ******************************************************************************/
20 #define _RTL8192C_XMIT_C_
21 #include <drv_conf.h>
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 #include <rtw_byteorder.h>
25 #include <wifi.h>
26 #include <osdep_intf.h>
27 #include <circ_buf.h>
28 #include <usb_ops.h>
29 #include <rtl8192d_hal.h>
30
31 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
32 #error "Shall be Linux or Windows, but not both!\n"
33 #endif
34
35
36 s32     rtl8192du_init_xmit_priv(_adapter *padapter)
37 {
38         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
39
40 #ifdef PLATFORM_LINUX
41         tasklet_init(&pxmitpriv->xmit_tasklet,
42              (void(*)(unsigned long))rtl8192du_xmit_tasklet,
43              (unsigned long)padapter);
44 #endif
45 #ifdef PLATFORM_FREEBSD
46                 TASK_INIT(&pxmitpriv->xmit_tasklet, 1, (task_fn_t *)rtl8192du_xmit_tasklet, (void *)padapter);
47 #endif
48
49         return _SUCCESS;
50 }
51
52 void    rtl8192du_free_xmit_priv(_adapter *padapter)
53 {
54 }
55
56 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe);
57 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
58 {
59         u32 addr;
60         struct pkt_attrib *pattrib = &pxmitframe->attrib;       
61         
62         switch(pattrib->qsel)
63         {
64                 case 0:
65                 case 3:
66                         addr = BE_QUEUE_INX;
67                         break;
68                 case 1:
69                 case 2:
70                         addr = BK_QUEUE_INX;
71                         break;                          
72                 case 4:
73                 case 5:
74                         addr = VI_QUEUE_INX;
75                         break;          
76                 case 6:
77                 case 7:
78                         addr = VO_QUEUE_INX;
79                         break;
80                 case 0x10:
81                         addr = BCN_QUEUE_INX;
82                         break;
83                 case 0x11://BC/MC in PS (HIQ)
84                         addr = HIGH_QUEUE_INX;
85                         break;
86                 case 0x12:
87                         addr = MGT_QUEUE_INX;
88                         break;
89                 default:
90                         addr = BE_QUEUE_INX;
91                         break;          
92                         
93         }
94
95         return addr;
96
97 }
98
99 int urb_zero_packet_chk(_adapter *padapter, int sz);
100 int urb_zero_packet_chk(_adapter *padapter, int sz)
101 {
102         int blnSetTxDescOffset;
103         struct dvobj_priv       *pdvobj = adapter_to_dvobj(padapter);
104
105         if ( pdvobj->ishighspeed )
106         {
107                 if ( ( (sz + TXDESC_SIZE) % 512 ) == 0 ) {
108                         blnSetTxDescOffset = 1;
109                 } else {
110                         blnSetTxDescOffset = 0;
111                 }
112         }
113         else
114         {
115                 if ( ( (sz + TXDESC_SIZE) % 64 ) == 0 )         {
116                         blnSetTxDescOffset = 1;
117                 } else {
118                         blnSetTxDescOffset = 0;
119                 }
120         }
121         
122         return blnSetTxDescOffset;
123         
124 }
125
126 void rtl8192du_cal_txdesc_chksum(struct tx_desc *ptxdesc)
127 {
128                 u16     *usPtr = (u16*)ptxdesc;
129                 u32 count = 16;         // (32 bytes / 2 bytes per XOR) => 16 times
130                 u32 index;
131                 u16 checksum = 0;
132
133                 //Clear first
134                 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
135         
136                 for(index = 0 ; index < count ; index++){
137                         checksum = checksum ^ le16_to_cpu(*(usPtr + index));
138                 }
139
140                 ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum);     
141
142 }
143
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)
146 {
147         if ((pattrib->encrypt > 0) && !pattrib->bswenc)
148         {
149                 switch (pattrib->encrypt)
150                 {       
151                         //SEC_TYPE
152                         case _WEP40_:
153                         case _WEP104_:
154                                         ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
155                                         break;                          
156                         case _TKIP_:
157                         case _TKIP_WTMIC_:      
158                                         //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
159                                         ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
160                                         break;
161                         case _AES_:
162                                         ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
163                                         break;
164                         case _NO_PRIVACY_:
165                         default:
166                                         break;
167                 
168                 }
169                 
170         }
171
172 }
173
174 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
175 {
176         //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);        
177
178         switch(pattrib->vcs_mode)
179         {
180                 case RTS_CTS:
181                         *pdw |= cpu_to_le32(BIT(12));
182                         break;
183                 case CTS_TO_SELF:
184                         *pdw |= cpu_to_le32(BIT(11));
185                         break;
186                 case NONE_VCS:
187                 default:
188                         break;          
189         }
190
191         if(pattrib->vcs_mode) {
192                 *pdw |= cpu_to_le32(BIT(13));
193
194                 // Set RTS BW
195                 if(pattrib->ht_en)
196                 {
197                         *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)?  cpu_to_le32(BIT(27)):0;
198
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)
204                                 *pdw |= 0;
205                         else
206                                 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
207                 }
208         }
209 }
210
211 static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
212 {
213         //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
214
215         if(pattrib->ht_en)
216         {
217                 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)?  cpu_to_le32(BIT(25)):0;
218
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)
224                         *pdw |= 0;
225                 else
226                         *pdw |= cpu_to_le32((0x03<<20)&0x00300000);
227         }
228 }
229
230 /*
231         Insert Early mode 's Content,8Byte
232 Len1    Len0    Pkt_num
233 Len4    Len3    Len2
234
235 */
236 VOID
237 InsertEMContent(IN struct xmit_frame *pxmitframe, IN u8 *VirtualAddress);
238 VOID
239 InsertEMContent(IN struct xmit_frame *pxmitframe, IN u8 *VirtualAddress)
240 {
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)
250 }
251
252 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
253 {
254         int     pull=0;
255         uint    qsel;
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);
267 #ifdef CONFIG_P2P
268         struct wifidirect_info  *pwdinfo = &padapter->wdinfo;
269         struct registry_priv    *pregistrypriv = &padapter->registrypriv;
270 #endif //CONFIG_P2P
271         
272
273 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
274 if (padapter->registrypriv.mp_mode == 0)
275 {
276
277         if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
278         {
279                 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
280                 pull = 1;
281                 pxmitframe->pkt_offset --;
282         }
283 }
284 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
285                 
286         _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
287
288         if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
289         {
290                 //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");                        
291
292                 //offset 4
293                 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
294
295                 qsel = (uint)(pattrib->qsel & 0x0000001f);
296                 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
297
298                 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
299
300                 fill_txdesc_sectype(pattrib, ptxdesc);
301
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);
309                                 }
310                         }
311                 }
312                 else
313                 {
314                         ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
315                 }
316
317                 //offset 8
318                 
319
320                 //offset 12
321                 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
322
323
324                 //offset 16 , offset 20
325                 if (pattrib->qos_en)
326                         ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS
327
328                 if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1))
329                 {
330                 //Non EAP & ARP & DHCP type data packet
331                 
332                         fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
333                         fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
334
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
338
339                         //use REG_INIDATA_RATE_SEL value
340                         ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);
341
342                 if(0)//for driver dbg
343                         {
344                                 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
345                                 
346                                 if(pattrib->ht_en)
347                                         ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI
348
349                                 ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7
350                         }
351
352                 }
353                 else
354                 {
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.
358
359                         ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
360                         
361                         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
362
363                         if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
364                                 ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT
365
366                         ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
367                 }
368                 
369 #ifdef CONFIG_P2P
370                 if(pregistrypriv->wifi_spec==1 && !rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
371                 {
372                         ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
373                         
374                         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
375
376                         ptxdesc->txdw5 = cpu_to_le32(0x0001ff00);//
377                 
378                         ptxdesc->txdw5 |= cpu_to_le32(BIT(2));// use OFDM 6Mbps
379                 }                       
380 #endif //CONFIG_P2P
381
382                 //offset 24
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);
389                 }
390 #endif
391         }
392         else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
393         {
394                 //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");        
395                 
396                 //offset 4              
397                 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
398                 
399                 qsel = (uint)(pattrib->qsel&0x0000001f);
400                 ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);
401
402                 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
403                 
404                 //fill_txdesc_sectype(pattrib, ptxdesc);
405                 
406                 //offset 8
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));
411                         #ifdef DBG_CCX
412                         DBG_871X("%s set ccx\n", __func__);
413                         #endif
414                 }
415 #endif //CONFIG_XMIT_ACK
416
417                 //offset 12
418                 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
419                 
420                 //offset 16
421                 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
422                 
423                 //offset 20
424 #ifdef CONFIG_AP_MODE
425                 if(check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
426                 {
427                         ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable
428 #ifdef CONFIG_P2P
429                         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
430                         {
431                                 ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2
432                         }
433                         else
434 #endif //CONFIG_P2P
435                                 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6                     
436                 }
437 #endif
438
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);
443                 }
444                 else
445 #endif
446                 {
447                         ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
448                 }
449         }
450         else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
451         {
452                 DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
453         }
454 #ifdef CONFIG_MP_INCLUDED
455         else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG)
456         {
457                 fill_txdesc_for_mp(padapter, ptxdesc);
458         }
459 #endif
460         else
461         {
462                 DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
463                 
464                 //offset 4      
465                 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID)
466                 
467                 ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid
468                 
469                 //offset 8              
470
471                 //offset 12
472                 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
473                 
474                 //offset 16
475                 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
476                 
477                 //offset 20
478                 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
479         }
480
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.
489         if(!pattrib->qos_en)
490         {               
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.
493         }
494
495         //offset 0
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
499         
500         if(bmcst)       
501         {
502                 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
503         }       
504
505         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0));
506
507         //offset 4
508         // pkt_offset, unit:8 bytes padding
509         if (pxmitframe->pkt_offset > 0)
510                 ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
511
512 #ifdef CONFIG_USB_TX_AGGREGATION
513         if (pxmitframe->agg_num > 1)
514                 ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000);
515 #endif
516
517         rtl8192du_cal_txdesc_chksum(ptxdesc);
518                 
519         return pull;
520                 
521 }
522
523 s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
524 {
525         s32 ret = _SUCCESS;
526         s32 inner_ret = _SUCCESS;
527         int t, sz, w_sz, pull=0;
528         u8 *mem_addr;
529         u32 ff_hwaddr;
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;
534 #ifdef CONFIG_TDLS
535         struct sta_priv         *pstapriv = &padapter->stapriv;
536         struct sta_info *ptdls_sta=NULL, *psta_backup=NULL;
537         u8 ra_backup[6];
538 #endif //CONFIG_TDLS
539
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))
544         {
545 #ifdef CONFIG_TDLS
546                 ptdls_sta = rtw_get_stainfo(pstapriv, pattrib->dst);
547                 if((ptdls_sta!=NULL)&&(ptdls_sta->tdls_sta_state & TDLS_LINKED_STATE))
548                 {
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);
556                 }
557 #endif //CONFIG_TDLS
558                 rtw_issue_addbareq_cmd(padapter, pxmitframe);
559         }
560
561         mem_addr = pxmitframe->buf_addr;
562
563        RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
564         
565         for (t = 0; t < pattrib->nr_frags; t++)
566         {
567                 if (inner_ret != _SUCCESS && ret == _SUCCESS)
568                         ret = _FAIL;
569
570                 if (t != (pattrib->nr_frags - 1))
571                 {
572                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
573
574                         sz = pxmitpriv->frag_len;
575                         sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);                                       
576                 }
577                 else //no frag
578                 {
579                         sz = pattrib->last_txcmdsz;
580                 }
581
582                 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
583                 
584                 if(pull)
585                 {
586                         mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
587                         
588                         //pxmitbuf ->pbuf = mem_addr;                   
589                         pxmitframe->buf_addr = mem_addr;
590
591                         w_sz = sz + TXDESC_SIZE;
592                 }
593                 else
594                 {
595                         w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
596                 }       
597
598                 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
599
600                 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
601
602                 rtw_count_tx_stats(padapter, pxmitframe, sz);
603
604
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);      
607
608                 mem_addr += w_sz;
609
610                 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
611
612         }
613         
614         rtw_free_xmitframe(pxmitpriv, pxmitframe);
615
616         if  (ret != _SUCCESS)
617                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
618
619         return ret;
620 }
621
622
623 #ifdef CONFIG_USB_TX_AGGREGATION
624 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
625 {
626         struct pkt_attrib *pattrib = &pxmitframe->attrib;
627
628         u32     len = 0;
629
630         // no consider fragement
631         len = pattrib->hdrlen + pattrib->iv_len +
632                 SNAP_SIZE + sizeof(u16) +
633                 pattrib->pktlen +
634                 ((pattrib->bswenc) ? pattrib->icv_len : 0);
635
636         if(pattrib->encrypt ==_TKIP_)
637                 len += 8;
638
639         return len;
640 }
641
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)
644 {
645         _irqL irqL;
646         u32     len;
647         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
648         struct pkt_attrib       *pattrib = &pxmitframe->attrib;
649         _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
650
651         //Some macaddr can't do early mode.
652         if(MacAddr_isBcst(pattrib->dst) ||IS_MCAST(pattrib->dst) || !!pattrib->qos_en)
653                 return;
654
655         pxmitframe->EMPktNum = 0;
656
657         // dequeue same priority packet from station tx queue
658         _enter_critical_bh(&pxmitpriv->lock, &irqL);
659
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))
663         {
664                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
665                 xmitframe_plist = get_next(xmitframe_plist);
666
667                 len = xmitframe_need_length(pxmitframe);
668                 pxmitframe->EMPktLen[pxmitframe->EMPktNum] = len;
669                 pxmitframe->EMPktNum++;
670         }
671         _exit_critical_bh(&pxmitpriv->lock, &irqL);
672
673 }
674
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)
677 {
678         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
679         struct xmit_frame *pxmitframe = NULL;
680         struct xmit_frame *pfirstframe = NULL;
681
682         // aggregate variable
683         struct hw_xmit  *phwxmit = pxmitpriv->hwxmits;
684         struct tx_servq *ptxservq = NULL;
685
686         _irqL irqL;
687         _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
688
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;
694         u32     bulkPtr=0;
695         u8      descCount=0;
696         u8      ac_index;
697         u8      bfirst = _TRUE;//first aggregation xmitframe
698         u8      bulkstart = _FALSE;
699
700         // dump frame variable
701         u32 ff_hwaddr;
702
703 #ifndef IDEA_CONDITION
704         int res = _SUCCESS;
705 #endif
706
707         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
708
709         // check xmitbuffer is ok
710         if (pxmitbuf == NULL) {
711                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
712                 if (pxmitbuf == NULL) return _FALSE;
713         }
714
715         if(pHalData->MacPhyMode92D==SINGLEMAC_SINGLEPHY)
716                 aggMaxLength = MAX_XMITBUF_SZ;
717         else
718                 aggMaxLength = 0x3D00;
719
720         do {
721                 //3 1. pick up first frame
722                 if(bfirst)
723                 {
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);
728                                 return _FALSE;
729                         }
730
731                         pxmitframe->pxmitbuf = pxmitbuf;
732                         pxmitframe->buf_addr = pxmitbuf->pbuf;
733                         pxmitbuf->priv_data = pxmitframe;
734
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
737
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);
742                 }
743                 //3 2. aggregate same priority and same DA(AP or STA) frames
744                 else
745                 {
746                         // dequeue same priority packet from station tx queue
747                         _enter_critical_bh(&pxmitpriv->lock, &irqL);
748
749                         if (_rtw_queue_empty(&ptxservq->sta_pending) == _FALSE)
750                         {
751                                 xmitframe_phead = get_list_head(&ptxservq->sta_pending);
752                                 xmitframe_plist = get_next(xmitframe_phead);
753
754                                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
755
756
757                                 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE + ((USB_92D_DUMMY_OFFSET - 1) * PACKET_OFFSET_SZ);
758                                 if (pbuf + _RND8(len) > aggMaxLength)
759                                 {
760                                         bulkstart = _TRUE;
761                                 }
762                                 else
763                                 {
764                                         rtw_list_delete(&pxmitframe->list);
765                                         ptxservq->qcnt--;
766                                         phwxmit[ac_index].accnt--;
767
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);
771                                 }
772                         }
773                         else
774                         {
775                                 bulkstart = _TRUE;
776                         }
777
778                         _exit_critical_bh(&pxmitpriv->lock, &irqL);
779
780                         if(bulkstart)
781                         {
782                                 break;
783                         }
784
785                         pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
786
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
789                 }
790
791                 if(pHalData->bEarlyModeEnable)
792                         UpdateEarlyModeInfo8192D(padapter, pxmitframe,ptxservq);
793
794
795                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
796                         DBG_871X("%s coalesce failed \n",__FUNCTION__);
797                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
798                         continue;
799                 }
800
801
802                 // always return ndis_packet after rtw_xmitframe_coalesce
803                 rtw_os_xmit_complete(padapter, pxmitframe);
804
805                 if(bfirst)
806                 {
807                         len = xmitframe_need_length(pfirstframe) + USB_HWDESC_HEADER_LEN;
808                         pbuf_tail = len;
809                         pbuf = _RND8(pbuf_tail);
810
811                         descCount = 0;
812                         bulkPtr = bulkSize;
813                         bfirst = _FALSE;
814                 }
815                 else
816                 {
817                         update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
818
819                         // don't need xmitframe any more
820                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
821
822                         // handle pointer and stop condition
823                         pbuf_tail = pbuf + len;
824                         pbuf = _RND8(pbuf_tail);
825
826                         pfirstframe->agg_num++;
827                         if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
828                                 break;
829                 }
830
831                 // check pkt amount in one bluk
832                 if (pbuf < bulkPtr)
833                 {
834                         descCount++;
835                         if (descCount == pHalData->UsbTxAggDescNum)
836                                 break;
837                 }
838                 else
839                 {
840                         descCount = 0;
841                         bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
842                 }
843         } while (1);
844
845         if ((pfirstframe->attrib.ether_type != 0x0806) &&
846             (pfirstframe->attrib.ether_type != 0x888e) &&
847             (pfirstframe->attrib.dhcp_pkt != 1))
848         {
849                 rtw_issue_addbareq_cmd(padapter, pfirstframe);
850         }
851
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--;
859         }
860 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
861         update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
862
863         //3 4. write xmit buffer to USB FIFO
864         ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
865
866         // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
867         rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
868
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);
873         
874         rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
875
876         rtw_free_xmitframe(pxmitpriv, pfirstframe);
877
878         return _TRUE;
879 }
880
881 #else
882
883 s32 rtl8192du_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
884 {               
885
886         struct hw_xmit *phwxmits;
887         sint hwentry;
888         struct xmit_frame *pxmitframe=NULL;     
889         int res=_SUCCESS, xcnt = 0;
890
891         phwxmits = pxmitpriv->hwxmits;
892         hwentry = pxmitpriv->hwxmit_entry;
893
894         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
895
896         if(pxmitbuf==NULL)
897         {
898                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);                
899                 if(!pxmitbuf)
900                 {
901                         return _FALSE;
902                 }                       
903         }
904
905         do
906         {               
907                 pxmitframe =  rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
908                 
909                 if(pxmitframe)
910                 {
911                         pxmitframe->pxmitbuf = pxmitbuf;                                
912
913                         pxmitframe->buf_addr = pxmitbuf->pbuf;
914
915                         pxmitbuf->priv_data = pxmitframe;       
916
917                         if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
918                         {       
919                                 if(pxmitframe->attrib.priority<=15)//TID0~15
920                                 {
921                                         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
922                                 }       
923                                                         
924                                 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce                     
925                         }       
926
927                                 
928                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
929
930                         
931                         if(res == _SUCCESS)
932                         {
933                                 rtw_dump_xframe(padapter, pxmitframe);
934                         }
935                         else
936                         {
937                                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
938                                 rtw_free_xmitframe(pxmitpriv, pxmitframe);      
939                         }
940                                                 
941                         xcnt++;
942                         
943                 }
944                 else
945                 {                       
946                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
947                         return _FALSE;
948                 }
949
950                 break;
951                 
952         }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
953
954         return _TRUE;
955         
956 }
957 #endif
958
959
960 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
961 {
962         s32 res = _SUCCESS;
963
964
965         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
966         if (res == _SUCCESS) {
967                 rtw_dump_xframe(padapter, pxmitframe);
968         }
969
970         return res;
971 }
972
973 /*
974  * Return
975  *      _TRUE   dump packet directly
976  *      _FALSE  enqueue packet
977  */
978 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
979 {
980         _irqL irqL;
981         s32 res;
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;
986         
987         _enter_critical_bh(&pxmitpriv->lock, &irqL);
988         
989 #ifdef PLATFORM_FREEBSD
990         //force tx to enqueue, and schedule tx task later.
991         goto enqueue;
992 #endif  // PLATFORM_FREEBSD
993
994         if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0
995 #ifdef CONFIG_DUALMAC_CONCURRENT
996                 || (dc_check_xmit(padapter)== _FALSE)
997 #endif
998                 )
999                 goto enqueue;
1000
1001
1002
1003         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1004                 goto enqueue;
1005
1006 #ifdef CONFIG_CONCURRENT_MODE
1007         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
1008                 goto enqueue;
1009 #endif //CONFIG_CONCURRENT_MODE
1010
1011         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
1012         if (pxmitbuf == NULL)
1013                 goto enqueue;
1014
1015         _exit_critical_bh(&pxmitpriv->lock, &irqL);
1016
1017         pxmitframe->pxmitbuf = pxmitbuf;
1018         pxmitframe->buf_addr = pxmitbuf->pbuf;
1019         pxmitbuf->priv_data = pxmitframe;
1020
1021         if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
1022                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
1023                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1024         }
1025
1026         return _TRUE;
1027
1028 enqueue:
1029         res = rtw_xmitframe_enqueue(padapter, pxmitframe);
1030         _exit_critical_bh(&pxmitpriv->lock, &irqL);
1031
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);
1035
1036                 // Trick, make the statistics correct
1037                 pxmitpriv->tx_pkts--;
1038                 pxmitpriv->tx_drop++;
1039                 return _TRUE;
1040         }
1041
1042 #ifdef PLATFORM_FREEBSD
1043         rtw_os_xmit_schedule(padapter);
1044 #endif  // PLATFORM_FREEBSD
1045
1046         return _FALSE;
1047 }
1048
1049 s32 rtl8192du_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
1050 {
1051         return rtw_dump_xframe(padapter, pmgntframe);
1052 }
1053
1054 /*
1055  * Return
1056  *      _TRUE   dump packet directly ok
1057  *      _FALSE  temporary can't transmit packets to hardware
1058  */
1059 s32 rtl8192du_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
1060 {
1061         return pre_xmitframe(padapter, pxmitframe);
1062 }
1063
1064 s32      rtl8192du_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
1065 {
1066         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
1067         s32 err;
1068         
1069         if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) 
1070         {
1071                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1072
1073                 // Trick, make the statistics correct
1074                 pxmitpriv->tx_pkts--;
1075                 pxmitpriv->tx_drop++;                                   
1076         }
1077         else
1078         {
1079 #ifdef PLATFORM_LINUX
1080                 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1081 #endif
1082         }
1083         
1084         return err;
1085         
1086 }
1087
1088 #ifdef  CONFIG_HOSTAPD_MLME
1089
1090 static void rtl8192du_hostap_mgnt_xmit_cb(struct urb *urb)
1091 {       
1092 #ifdef PLATFORM_LINUX
1093         struct sk_buff *skb = (struct sk_buff *)urb->context;
1094
1095         //DBG_8192C("%s\n", __FUNCTION__);
1096
1097         rtw_skb_free(skb);
1098 #endif  
1099 }
1100
1101 s32 rtl8192du_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1102 {
1103 #ifdef PLATFORM_LINUX
1104         u16 fc;
1105         int rc, len, pipe;      
1106         unsigned int bmcst, tid, qsel;
1107         struct sk_buff *skb, *pxmit_skb;
1108         struct urb *urb;
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);
1116
1117         
1118         //DBG_8192C("%s\n", __FUNCTION__);
1119
1120         skb = pkt;
1121         
1122         len = skb->len;
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);
1126
1127         if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
1128                 goto _exit;
1129
1130         pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
1131
1132         if(!pxmit_skb)
1133                 goto _exit;
1134
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
1141         if (!urb) {
1142                 goto _exit;
1143         }
1144
1145         // ----- fill tx desc -----     
1146         ptxdesc = (struct tx_desc *)pxmitbuf;   
1147         _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1148                 
1149         //offset 0      
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);
1153
1154         if(bmcst)       
1155         {
1156                 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1157         }       
1158
1159         //offset 4      
1160         ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
1161
1162         ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
1163
1164         ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
1165
1166         //offset 8                      
1167
1168         //offset 12             
1169         ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
1170
1171         //offset 16             
1172         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
1173                 
1174         //offset 20
1175
1176
1177         //HW append seq
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.
1180         
1181
1182         rtl8192cu_cal_txdesc_chksum(ptxdesc);
1183         // ----- end of fill tx desc -----
1184
1185         //
1186         skb_put(pxmit_skb, len + TXDESC_SIZE);
1187         pxmitbuf = pxmitbuf + TXDESC_SIZE;
1188         _rtw_memcpy(pxmitbuf, skb->data, len);
1189
1190         //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
1191
1192
1193         // ----- prepare urb for submit -----
1194         
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
1205         
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
1213         if (rc < 0) {
1214                 usb_unanchor_urb(urb);
1215                 kfree_skb(skb);
1216         }
1217 #ifdef PLATFORM_FREEBSD
1218         rtw_usb_free_urb(urb);
1219 #else //PLATFORM_FREEBSD
1220         usb_free_urb(urb);
1221 #endif //PLATFORM_FREEBSD
1222
1223         
1224 _exit:  
1225         
1226         rtw_skb_free(skb);
1227
1228 #endif
1229
1230         return 0;
1231
1232 }
1233 #endif
1234
1235