add rk3288 pinctrl dts code
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rtl8192cu / hal / rtl8192c / usb / rtl8192cu_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 <rtl8192c_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     rtl8192cu_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))rtl8192cu_xmit_tasklet,
43              (unsigned long)padapter);
44 #endif
45         return _SUCCESS;
46 }
47
48 void    rtl8192cu_free_xmit_priv(_adapter *padapter)
49 {
50 }
51
52 u32 rtw_get_ff_hwaddr(struct xmit_frame *pxmitframe)
53 {
54         u32 addr;
55         struct pkt_attrib *pattrib = &pxmitframe->attrib;       
56         
57         switch(pattrib->qsel)
58         {
59                 case 0:
60                 case 3:
61                         addr = BE_QUEUE_INX;
62                         break;
63                 case 1:
64                 case 2:
65                         addr = BK_QUEUE_INX;
66                         break;                          
67                 case 4:
68                 case 5:
69                         addr = VI_QUEUE_INX;
70                         break;          
71                 case 6:
72                 case 7:
73                         addr = VO_QUEUE_INX;
74                         break;
75                 case 0x10:
76                         addr = BCN_QUEUE_INX;
77                         break;
78                 case 0x11://BC/MC in PS (HIQ)
79                         addr = HIGH_QUEUE_INX;
80                         break;
81                 case 0x12:
82                         addr = MGT_QUEUE_INX;
83                         break;
84                 default:
85                         addr = BE_QUEUE_INX;
86                         break;          
87                         
88         }
89
90         return addr;
91
92 }
93
94 int urb_zero_packet_chk(_adapter *padapter, int sz)
95 {
96         int blnSetTxDescOffset;
97         struct dvobj_priv       *pdvobj = adapter_to_dvobj(padapter);   
98
99         if ( pdvobj->ishighspeed )
100         {
101                 if ( ( (sz + TXDESC_SIZE) % 512 ) == 0 ) {
102                         blnSetTxDescOffset = 1;
103                 } else {
104                         blnSetTxDescOffset = 0;
105                 }
106         }
107         else
108         {
109                 if ( ( (sz + TXDESC_SIZE) % 64 ) == 0 )         {
110                         blnSetTxDescOffset = 1;
111                 } else {
112                         blnSetTxDescOffset = 0;
113                 }
114         }
115         
116         return blnSetTxDescOffset;
117         
118 }
119
120 void rtl8192cu_cal_txdesc_chksum(struct tx_desc *ptxdesc)
121 {
122                 u16     *usPtr = (u16*)ptxdesc;
123                 u32 count = 16;         // (32 bytes / 2 bytes per XOR) => 16 times
124                 u32 index;
125                 u16 checksum = 0;
126
127                 //Clear first
128                 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
129         
130                 for(index = 0 ; index < count ; index++){
131                         checksum = checksum ^ le16_to_cpu(*(usPtr + index));
132                 }
133
134                 ptxdesc->txdw7 |= cpu_to_le32(0x0000ffff&checksum);     
135
136 }
137
138 void fill_txdesc_sectype(struct pkt_attrib *pattrib, struct tx_desc *ptxdesc)
139 {
140         if ((pattrib->encrypt > 0) && !pattrib->bswenc)
141         {
142                 switch (pattrib->encrypt)
143                 {       
144                         //SEC_TYPE
145                         case _WEP40_:
146                         case _WEP104_:
147                                         ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
148                                         break;                          
149                         case _TKIP_:
150                         case _TKIP_WTMIC_:      
151                                         //ptxdesc->txdw1 |= cpu_to_le32((0x02<<22)&0x00c00000);
152                                         ptxdesc->txdw1 |= cpu_to_le32((0x01<<22)&0x00c00000);
153                                         break;
154                         case _AES_:
155                                         ptxdesc->txdw1 |= cpu_to_le32((0x03<<22)&0x00c00000);
156                                         break;
157                         case _NO_PRIVACY_:
158                         default:
159                                         break;
160                 
161                 }
162                 
163         }
164
165 }
166
167 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, u32 *pdw)
168 {
169         //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);        
170
171         switch(pattrib->vcs_mode)
172         {
173                 case RTS_CTS:
174                         *pdw |= cpu_to_le32(BIT(12));
175                         break;
176                 case CTS_TO_SELF:
177                         *pdw |= cpu_to_le32(BIT(11));
178                         break;
179                 case NONE_VCS:
180                 default:
181                         break;          
182         }
183
184         if(pattrib->vcs_mode) {
185                 *pdw |= cpu_to_le32(BIT(13));
186
187                 // Set RTS BW
188                 if(pattrib->ht_en)
189                 {
190                         *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)?  cpu_to_le32(BIT(27)):0;
191
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)
197                                 *pdw |= 0;
198                         else
199                                 *pdw |= cpu_to_le32((0x03<<28)&0x30000000);
200                 }
201         }
202 }
203
204 static void fill_txdesc_phy(struct pkt_attrib *pattrib, u32 *pdw)
205 {
206         //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
207
208         if(pattrib->ht_en)
209         {
210                 *pdw |= (pattrib->bwmode&HT_CHANNEL_WIDTH_40)?  cpu_to_le32(BIT(25)):0;
211
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)
217                         *pdw |= 0;
218                 else
219                         *pdw |= cpu_to_le32((0x03<<20)&0x00300000);
220         }
221 }
222
223 static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz, u8 bagg_pkt)
224 {
225         int     pull=0;
226         uint    qsel;
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);
237 #ifdef CONFIG_P2P
238         struct wifidirect_info* pwdinfo = &padapter->wdinfo;
239 #endif //CONFIG_P2P
240
241 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
242         if((_FALSE == bagg_pkt) && (urb_zero_packet_chk(padapter, sz)==0))
243         {
244                 ptxdesc = (struct tx_desc *)(pmem+PACKET_OFFSET_SZ);
245                 pull = 1;
246                 pxmitframe->pkt_offset --;
247         }
248 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
249
250         _rtw_memset(ptxdesc, 0, sizeof(struct tx_desc));
251
252         if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
253         {
254                 //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");                        
255
256                 //offset 4
257                 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
258
259                 qsel = (uint)(pattrib->qsel & 0x0000001f);
260                 ptxdesc->txdw1 |= cpu_to_le32((qsel << QSEL_SHT) & 0x00001f00);
261
262                 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
263
264                 fill_txdesc_sectype(pattrib, ptxdesc);
265
266                 if(pattrib->ampdu_en==_TRUE)
267                         ptxdesc->txdw1 |= cpu_to_le32(BIT(5));//AGG EN
268                 else
269                         ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
270                 
271                 //offset 8
272
273
274                 //offset 12
275                 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
276
277
278                 //offset 16 , offset 20
279                 if (pattrib->qos_en)
280                         ptxdesc->txdw4 |= cpu_to_le32(BIT(6));//QoS
281
282                 if ((pattrib->ether_type != 0x888e) && (pattrib->ether_type != 0x0806) && (pattrib->dhcp_pkt != 1))
283                 {
284                 //Non EAP & ARP & DHCP type data packet
285                 
286                         fill_txdesc_vcs(pattrib, &ptxdesc->txdw4);
287                         fill_txdesc_phy(pattrib, &ptxdesc->txdw4);
288
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
292
293                         //use REG_INIDATA_RATE_SEL value
294                         ptxdesc->txdw5 |= cpu_to_le32(pdmpriv->INIDATA_RATE[pattrib->mac_id]);
295
296                 if(0)//for driver dbg
297                         {
298                                 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
299                                 
300                                 if(pattrib->ht_en)
301                                         ptxdesc->txdw5 |= cpu_to_le32(BIT(6));//SGI
302
303                                 ptxdesc->txdw5 |= cpu_to_le32(0x00000013);//init rate - mcs7
304                         }
305
306                 }
307                 else
308                 {
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.
312
313                         ptxdesc->txdw1 |= cpu_to_le32(BIT(6));//AGG BK
314                         
315                         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
316
317                         if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
318                                 ptxdesc->txdw4 |= cpu_to_le32(BIT(24));// DATA_SHORT
319
320                         ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
321                 }
322                 
323                 //offset 24
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);
330                 }
331 #endif
332         }
333         else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
334         {
335                 //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");        
336                 
337                 //offset 4              
338                 ptxdesc->txdw1 |= cpu_to_le32(pattrib->mac_id&0x1f);
339                 
340                 qsel = (uint)(pattrib->qsel&0x0000001f);
341                 ptxdesc->txdw1 |= cpu_to_le32((qsel<<QSEL_SHT)&0x00001f00);
342
343                 ptxdesc->txdw1 |= cpu_to_le32((pattrib->raid<< 16) & 0x000f0000);
344                 
345                 //fill_txdesc_sectype(pattrib, ptxdesc);
346                 
347                 //offset 8              
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));
352                         #ifdef DBG_CCX
353                         DBG_871X("%s set ccx\n", __func__);
354                         #endif
355                 }
356 #endif //CONFIG_XMIT_ACK
357
358                 //offset 12
359                 ptxdesc->txdw3 |= cpu_to_le32((pattrib->seqnum<<16)&0xffff0000);
360                 
361                 //offset 16
362                 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
363                 
364                 //offset 20
365                 ptxdesc->txdw5 |= cpu_to_le32(BIT(17));//retry limit enable
366                 if(pattrib->retry_ctrl == _TRUE)
367                 {
368 #ifdef CONFIG_P2P
369                         if(!rtw_p2p_chk_state(pwdinfo, P2P_STATE_NONE))
370                         {
371 #ifdef CONFIG_INTEL_WIDI
372                                 if(padapter->mlmepriv.widi_enable == _TRUE)
373                                         ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6
374                                 else
375 #endif //CONFIG_INTEL_WIDI
376                                         ptxdesc->txdw5 |= cpu_to_le32(0x00080000);//retry limit = 2
377                         }
378                         else
379 #endif //CONFIG_P2P
380                                 ptxdesc->txdw5 |= cpu_to_le32(0x00180000);//retry limit = 6                     
381                 }
382                 else
383                         ptxdesc->txdw5 |= cpu_to_le32(0x00300000);//retry limit = 12
384
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);
389                 }
390                 else
391 #endif
392                 {
393                         ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
394                 }
395         }
396         else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
397         {
398                 DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
399         }
400 #ifdef CONFIG_MP_INCLUDED
401         else if((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG)
402         {
403                 fill_txdesc_for_mp(padapter, ptxdesc);
404         }
405 #endif
406         else
407         {
408                 DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
409                 
410                 //offset 4      
411                 ptxdesc->txdw1 |= cpu_to_le32((4)&0x1f);//CAM_ID(MAC_ID)
412                 
413                 ptxdesc->txdw1 |= cpu_to_le32((6<< 16) & 0x000f0000);//raid
414                 
415                 //offset 8              
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                 ptxdesc->txdw5 |= cpu_to_le32(MRateToHwRate(pmlmeext->tx_rate));
425         }
426
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.
435         if(!pattrib->qos_en)
436         {               
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.
439         }
440
441         //offset 0
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
445
446         if(bmcst)       
447         {
448                 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
449         }       
450
451         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("offset0-txdesc=0x%x\n", ptxdesc->txdw0));
452
453         //offset 4
454         // pkt_offset, unit:8 bytes padding
455         if (pxmitframe->pkt_offset > 0)
456                 ptxdesc->txdw1 |= cpu_to_le32((pxmitframe->pkt_offset << 26) & 0x7c000000);
457
458 #ifdef CONFIG_USB_TX_AGGREGATION
459         if (pxmitframe->agg_num > 1)
460                 ptxdesc->txdw5 |= cpu_to_le32((pxmitframe->agg_num << 24) & 0xff000000);
461 #endif
462
463         rtl8192cu_cal_txdesc_chksum(ptxdesc);
464                 
465         return pull;
466                 
467 }
468
469 static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
470 {
471         s32 ret = _SUCCESS;
472         s32 inner_ret = _SUCCESS;
473         int t, sz, w_sz, pull=0;
474         u8 *mem_addr;
475         u32 ff_hwaddr;
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;
480
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))
485         {
486                 rtw_issue_addbareq_cmd(padapter, pxmitframe);
487         }
488         
489         mem_addr = pxmitframe->buf_addr;
490
491        RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
492         
493         for (t = 0; t < pattrib->nr_frags; t++)
494         {
495                 if (inner_ret != _SUCCESS && ret == _SUCCESS)
496                         ret = _FAIL;
497
498                 if (t != (pattrib->nr_frags - 1))
499                 {
500                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
501
502                         sz = pxmitpriv->frag_len;
503                         sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);                                       
504                 }
505                 else //no frag
506                 {
507                         sz = pattrib->last_txcmdsz;
508                 }
509
510                 pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
511                 
512                 if(pull)
513                 {
514                         mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
515                         
516                         //pxmitbuf ->pbuf = mem_addr;                   
517                         pxmitframe->buf_addr = mem_addr;
518
519                         w_sz = sz + TXDESC_SIZE;
520                 }
521                 else
522                 {
523                         w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
524                 }       
525
526                 ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
527                 
528                 inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
529
530                 rtw_count_tx_stats(padapter, pxmitframe, sz);
531
532
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);      
535
536                 mem_addr += w_sz;
537
538                 mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
539
540         }
541         
542         rtw_free_xmitframe(pxmitpriv, pxmitframe);
543
544         if  (ret != _SUCCESS)
545                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
546
547         return ret;
548 }
549
550 #ifdef CONFIG_USB_TX_AGGREGATION
551 static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
552 {
553         struct pkt_attrib *pattrib = &pxmitframe->attrib;
554
555         u32     len = 0;
556
557         // no consider fragement
558         len = pattrib->hdrlen + pattrib->iv_len +
559                 SNAP_SIZE + sizeof(u16) +
560                 pattrib->pktlen +
561                 ((pattrib->bswenc) ? pattrib->icv_len : 0);
562
563         if(pattrib->encrypt ==_TKIP_)
564                 len += 8;
565
566         return len;
567 }
568
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)
571 {
572         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
573         struct xmit_frame *pxmitframe = NULL;
574         struct xmit_frame *pfirstframe = NULL;
575
576         // aggregate variable
577         struct hw_xmit *phwxmit;
578         struct sta_info *psta = NULL;
579         struct tx_servq *ptxservq = NULL;
580
581         _irqL irqL;
582         _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
583
584         u32     pbuf;   // next pkt address
585         u32     pbuf_tail;      // last pkt tail
586         u32     len;    // packet length, except TXDESC_SIZE and PKT_OFFSET
587
588         u32     bulkSize = pHalData->UsbBulkOutSize;
589         u8      descCount;
590         u32     bulkPtr;
591
592         // dump frame variable
593         u32 ff_hwaddr;
594
595 #ifndef IDEA_CONDITION
596         int res = _SUCCESS;
597 #endif
598
599         RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
600
601
602         // check xmitbuffer is ok
603         if (pxmitbuf == NULL) {
604                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
605                 if (pxmitbuf == NULL) return _FALSE;
606         }
607
608
609         //3 1. pick up first frame
610         do {
611                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
612                         
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);
617                         return _FALSE;
618                 }
619
620
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);
627                         continue;
628                 }
629
630                 // TID 0~15
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);
637                         continue;
638                 }
639 #endif
640
641                 pxmitframe->pxmitbuf = pxmitbuf;
642                 pxmitframe->buf_addr = pxmitbuf->pbuf;
643                 pxmitbuf->priv_data = pxmitframe;
644
645                 //pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
646                 pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
647
648
649                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
650                         DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
651                         continue;
652                 }
653
654
655                 // always return ndis_packet after rtw_xmitframe_coalesce
656                 rtw_os_xmit_complete(padapter, pxmitframe);
657
658                 break;
659         } while (1);
660
661         //3 2. aggregate same priority and same DA(AP or STA) frames
662         pfirstframe = pxmitframe;
663         len = xmitframe_need_length(pfirstframe) + TXDESC_OFFSET;
664         pbuf_tail = len;
665         pbuf = _RND8(pbuf_tail);
666
667         // check pkt amount in one bluk
668         descCount = 0;
669         bulkPtr = bulkSize;
670         if (pbuf < bulkPtr)
671                 descCount++;
672         else {
673                 descCount = 0;
674                 bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
675         }
676
677         // dequeue same priority packet from station tx queue
678         psta = pfirstframe->attrib.psta;
679         switch (pfirstframe->attrib.priority) {
680                 case 1:
681                 case 2:
682                         ptxservq = &(psta->sta_xmitpriv.bk_q);
683                         phwxmit = pxmitpriv->hwxmits + 3;
684                         break;
685
686                 case 4:
687                 case 5:
688                         ptxservq = &(psta->sta_xmitpriv.vi_q);
689                         phwxmit = pxmitpriv->hwxmits + 1;
690                         break;
691
692                 case 6:
693                 case 7:
694                         ptxservq = &(psta->sta_xmitpriv.vo_q);
695                         phwxmit = pxmitpriv->hwxmits;
696                         break;
697
698                 case 0:
699                 case 3:
700                 default:
701                         ptxservq = &(psta->sta_xmitpriv.be_q);
702                         phwxmit = pxmitpriv->hwxmits + 2;
703                         break;
704         }
705
706         _enter_critical_bh(&pxmitpriv->lock, &irqL);
707
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)
711         {
712                 pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
713                 xmitframe_plist = get_next(xmitframe_plist);
714
715                 len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE; // no offset
716                 if (pbuf + len > MAX_XMITBUF_SZ) break;
717
718                 rtw_list_delete(&pxmitframe->list);
719                 ptxservq->qcnt--;
720                 phwxmit->accnt--;
721
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);
729                         continue;
730                 }
731
732                 // TID 0~15
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);
739                         continue;
740                 }
741 #endif
742
743 //              pxmitframe->pxmitbuf = pxmitbuf;
744                 pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
745
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
748
749                 if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
750                         DBG_871X("%s coalesce failed \n",__FUNCTION__);
751                         rtw_free_xmitframe(pxmitpriv, pxmitframe);
752                         continue;
753                 }
754
755                 // always return ndis_packet after rtw_xmitframe_coalesce
756                 rtw_os_xmit_complete(padapter, pxmitframe);
757
758                 // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
759                 update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz, _TRUE);
760
761                 // don't need xmitframe any more
762                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
763
764                 // handle pointer and stop condition
765                 pbuf_tail = pbuf + len;
766                 pbuf = _RND8(pbuf_tail);
767
768                 pfirstframe->agg_num++;
769                 if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
770                         break;
771
772                 if (pbuf < bulkPtr) {
773                         descCount++;
774                         if (descCount == pHalData->UsbTxAggDescNum)
775                                 break;
776                 } else {
777                         descCount = 0;
778                         bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
779                 }
780         }
781         if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
782                 rtw_list_delete(&ptxservq->tx_pending);
783
784         _exit_critical_bh(&pxmitpriv->lock, &irqL);
785
786         if ((pfirstframe->attrib.ether_type != 0x0806) &&
787             (pfirstframe->attrib.ether_type != 0x888e) &&
788             (pfirstframe->attrib.dhcp_pkt != 1))
789         {
790                 rtw_issue_addbareq_cmd(padapter, pfirstframe);
791         }
792
793 #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
794         //3 3. update first frame txdesc
795         if ((pbuf_tail % bulkSize) == 0) {
796                 // remove pkt_offset
797                 pbuf_tail -= PACKET_OFFSET_SZ;
798                 pfirstframe->buf_addr += PACKET_OFFSET_SZ;
799                 pfirstframe->pkt_offset = 0;
800         }
801 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_TX
802         update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz, _TRUE);
803
804         //3 4. write xmit buffer to USB FIFO
805         ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
806
807         // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
808         rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
809
810
811         //3 5. update statisitc
812         pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
813         if (pfirstframe->pkt_offset == 1) pbuf_tail -= PACKET_OFFSET_SZ;
814         
815         rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
816
817         rtw_free_xmitframe(pxmitpriv, pfirstframe);
818
819         return _TRUE;
820 }
821
822 #else
823
824 s32 rtl8192cu_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
825 {               
826
827         struct hw_xmit *phwxmits;
828         sint hwentry;
829         struct xmit_frame *pxmitframe=NULL;     
830         int res=_SUCCESS, xcnt = 0;
831
832         phwxmits = pxmitpriv->hwxmits;
833         hwentry = pxmitpriv->hwxmit_entry;
834
835         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
836
837         if(pxmitbuf==NULL)
838         {
839                 pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);                
840                 if(!pxmitbuf)
841                 {
842                         return _FALSE;
843                 }                       
844         }       
845
846
847         do
848         {               
849                 pxmitframe =  rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
850                 
851                 if(pxmitframe)
852                 {
853                         pxmitframe->pxmitbuf = pxmitbuf;                                
854
855                         pxmitframe->buf_addr = pxmitbuf->pbuf;
856
857                         pxmitbuf->priv_data = pxmitframe;       
858
859                         if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
860                         {       
861                                 if(pxmitframe->attrib.priority<=15)//TID0~15
862                                 {
863                                         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
864                                 }       
865                                                         
866                                 rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce                     
867                         }
868
869                                 
870                         RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
871
872                         
873                         if(res == _SUCCESS)
874                         {
875                                 rtw_dump_xframe(padapter, pxmitframe);
876                         }
877                         else
878                         {
879                                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
880                                 rtw_free_xmitframe(pxmitpriv, pxmitframe);      
881                         }
882                                                 
883                         xcnt++;
884                         
885                 }
886                 else
887                 {                       
888                         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
889                         return _FALSE;
890                 }
891
892                 break;
893                 
894         }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
895
896         return _TRUE;
897         
898 }
899 #endif
900
901
902
903 static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
904 {
905         s32 res = _SUCCESS;
906
907
908         res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
909         if (res == _SUCCESS) {
910                 rtw_dump_xframe(padapter, pxmitframe);
911         }
912
913         return res;
914 }
915
916 /*
917  * Return
918  *      _TRUE   dump packet directly
919  *      _FALSE  enqueue packet
920  */
921 static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
922 {
923         _irqL irqL;
924         s32 res;
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;
929         
930         
931         _enter_critical_bh(&pxmitpriv->lock, &irqL);
932
933
934         if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
935                 goto enqueue;
936
937
938         if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
939                 goto enqueue;
940
941 #ifdef CONFIG_CONCURRENT_MODE   
942         if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
943                 goto enqueue;
944 #endif
945
946         pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
947         if (pxmitbuf == NULL)
948                 goto enqueue;
949
950         _exit_critical_bh(&pxmitpriv->lock, &irqL);
951
952         pxmitframe->pxmitbuf = pxmitbuf;
953         pxmitframe->buf_addr = pxmitbuf->pbuf;
954         pxmitbuf->priv_data = pxmitframe;
955
956         if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
957                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
958                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
959         }
960
961         return _TRUE;
962
963 enqueue:
964         res = rtw_xmitframe_enqueue(padapter, pxmitframe);
965         _exit_critical_bh(&pxmitpriv->lock, &irqL);
966
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);
970
971                 // Trick, make the statistics correct
972                 pxmitpriv->tx_pkts--;
973                 pxmitpriv->tx_drop++;
974                 return _TRUE;
975         }
976
977         return _FALSE;
978 }
979
980 s32 rtl8192cu_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
981 {
982         return rtw_dump_xframe(padapter, pmgntframe);
983 }
984
985 /*
986  * Return
987  *      _TRUE   dump packet directly ok
988  *      _FALSE  temporary can't transmit packets to hardware
989  */
990 s32 rtl8192cu_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
991 {
992         return pre_xmitframe(padapter, pxmitframe);
993 }
994
995 s32      rtl8192cu_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
996 {
997         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
998         s32 err;
999         
1000         if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS) 
1001         {
1002                 rtw_free_xmitframe(pxmitpriv, pxmitframe);
1003
1004                 // Trick, make the statistics correct
1005                 pxmitpriv->tx_pkts--;
1006                 pxmitpriv->tx_drop++;                                   
1007         }
1008         else
1009         {
1010 #ifdef PLATFORM_LINUX
1011                 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
1012 #endif
1013         }
1014         
1015         return err;
1016         
1017 }
1018
1019 #ifdef  CONFIG_HOSTAPD_MLME
1020
1021 static void rtl8192cu_hostap_mgnt_xmit_cb(struct urb *urb)
1022 {       
1023 #ifdef PLATFORM_LINUX
1024         struct sk_buff *skb = (struct sk_buff *)urb->context;
1025
1026         //DBG_8192C("%s\n", __FUNCTION__);
1027
1028         rtw_skb_free(skb);
1029 #endif  
1030 }
1031
1032 s32 rtl8192cu_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
1033 {
1034 #ifdef PLATFORM_LINUX
1035         u16 fc;
1036         int rc, len, pipe;      
1037         unsigned int bmcst, tid, qsel;
1038         struct sk_buff *skb, *pxmit_skb;
1039         struct urb *urb;
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); 
1047
1048         
1049         //DBG_8192C("%s\n", __FUNCTION__);
1050
1051         skb = pkt;
1052         
1053         len = skb->len;
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);
1057
1058         if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
1059                 goto _exit;
1060
1061         pxmit_skb = rtw_skb_alloc(len + TXDESC_SIZE);
1062
1063         if(!pxmit_skb)
1064                 goto _exit;
1065
1066         pxmitbuf = pxmit_skb->data;
1067
1068         urb = usb_alloc_urb(0, GFP_ATOMIC);
1069         if (!urb) {
1070                 goto _exit;
1071         }
1072
1073         // ----- fill tx desc -----     
1074         ptxdesc = (struct tx_desc *)pxmitbuf;   
1075         _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
1076                 
1077         //offset 0      
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);
1081
1082         if(bmcst)       
1083         {
1084                 ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
1085         }       
1086
1087         //offset 4      
1088         ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
1089
1090         ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
1091
1092         ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
1093
1094         //offset 8                      
1095
1096         //offset 12             
1097         ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
1098
1099         //offset 16             
1100         ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
1101                 
1102         //offset 20
1103
1104
1105         //HW append seq
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.
1108         
1109
1110         rtl8192cu_cal_txdesc_chksum(ptxdesc);
1111         // ----- end of fill tx desc -----
1112
1113         //
1114         skb_put(pxmit_skb, len + TXDESC_SIZE);
1115         pxmitbuf = pxmitbuf + TXDESC_SIZE;
1116         _rtw_memcpy(pxmitbuf, skb->data, len);
1117
1118         //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
1119
1120
1121         // ----- prepare urb for submit -----
1122         
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);
1126         
1127         usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
1128                           pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
1129         
1130         urb->transfer_flags |= URB_ZERO_PACKET;
1131         usb_anchor_urb(urb, &phostapdpriv->anchored);
1132         rc = usb_submit_urb(urb, GFP_ATOMIC);
1133         if (rc < 0) {
1134                 usb_unanchor_urb(urb);
1135                 kfree_skb(skb);
1136         }
1137         usb_free_urb(urb);
1138
1139         
1140 _exit:  
1141         
1142         rtw_skb_free(skb);
1143
1144 #endif
1145
1146         return 0;
1147
1148 }
1149 #endif
1150