OSDN Git Service

rtl8723au: Upgrade to driver version v4.1.6_7336.20130426
[android-x86/external-modules-rtl8723au.git] / hal / usb_ops_linux.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 _HCI_OPS_OS_C_
21
22 #include <drv_conf.h>
23 #include <osdep_service.h>
24 #include <drv_types.h>
25 #include <osdep_intf.h>
26 #include <usb_ops.h>
27 #include <circ_buf.h>
28 #include <recv_osdep.h>
29 //#include <rtl8192c_hal.h>
30 #include <rtl8723a_hal.h>
31 #include <rtl8723a_recv.h>
32 #if defined (PLATFORM_LINUX) && defined (PLATFORM_WINDOWS)
33
34 #error "Shall be Linux or Windows, but not both!\n"
35
36 #endif
37
38 static int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
39 {
40         _adapter                *padapter = pintfhdl->padapter ;
41         struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
42         struct usb_device *udev=pdvobjpriv->pusbdev;
43
44         unsigned int pipe;
45         int status = 0;
46         u32 tmp_buflen=0;
47         u8 reqtype;
48         u8 *pIo_buf;
49         int vendorreq_times = 0;
50
51         #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
52         u8 *tmp_buf;
53         #else // use stack memory
54         u8 tmp_buf[MAX_USB_IO_CTL_SIZE];
55         #endif
56
57 #ifdef CONFIG_CONCURRENT_MODE
58         if(padapter->adapter_type > PRIMARY_ADAPTER)
59         {
60                 padapter = padapter->pbuddy_adapter;
61                 pdvobjpriv = adapter_to_dvobj(padapter);
62                 udev = pdvobjpriv->pusbdev;
63         }
64 #endif
65
66
67         //DBG_8723A("%s %s:%d\n",__FUNCTION__, current->comm, current->pid);
68
69         if((padapter->bSurpriseRemoved) ||(padapter->pwrctrlpriv.pnp_bstop_trx)){
70                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usbctrl_vendorreq:(padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
71                 status = -EPERM;
72                 goto exit;
73         }
74
75         if(len>MAX_VENDOR_REQ_CMD_SIZE){
76                 DBG_8723A( "[%s] Buffer len error ,vendor request failed\n", __FUNCTION__ );
77                 status = -EINVAL;
78                 goto exit;
79         }
80
81         #ifdef CONFIG_USB_VENDOR_REQ_MUTEX
82         _enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL);
83         #endif
84
85
86         // Acquire IO memory for vendorreq
87 #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC
88         pIo_buf = pdvobjpriv->usb_vendor_req_buf;
89 #else
90         #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
91         tmp_buf = rtw_malloc( (u32) len + ALIGNMENT_UNIT);
92         tmp_buflen =  (u32)len + ALIGNMENT_UNIT;
93         #else // use stack memory
94         tmp_buflen = MAX_USB_IO_CTL_SIZE;
95         #endif
96
97         // Added by Albert 2010/02/09
98         // For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment.
99         // Trying to fix it here.
100         pIo_buf = (tmp_buf==NULL)?NULL:tmp_buf + ALIGNMENT_UNIT -((SIZE_PTR)(tmp_buf) & 0x0f );
101 #endif
102
103         if ( pIo_buf== NULL) {
104                 DBG_8723A( "[%s] pIo_buf == NULL \n", __FUNCTION__ );
105                 status = -ENOMEM;
106                 goto release_mutex;
107         }
108
109         while(++vendorreq_times<= MAX_USBCTRL_VENDORREQ_TIMES)
110         {
111                 _rtw_memset(pIo_buf, 0, len);
112
113                 if (requesttype == 0x01)
114                 {
115                         pipe = usb_rcvctrlpipe(udev, 0);//read_in
116                         reqtype =  REALTEK_USB_VENQT_READ;
117                 }
118                 else
119                 {
120                         pipe = usb_sndctrlpipe(udev, 0);//write_out
121                         reqtype =  REALTEK_USB_VENQT_WRITE;
122                         _rtw_memcpy( pIo_buf, pdata, len);
123                 }
124
125                 #if 0
126                 //timeout test for firmware downloading
127                 status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len
128                         , ((value >= FW_8192C_START_ADDRESS && value <= FW_8192C_END_ADDRESS) ||value!=0x1000) ?RTW_USB_CONTROL_MSG_TIMEOUT : RTW_USB_CONTROL_MSG_TIMEOUT_TEST
129                 );
130                 #else
131                 status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
132                 #endif
133
134                 if ( status == len)   // Success this control transfer.
135                 {
136                         rtw_reset_continual_urb_error(pdvobjpriv);
137                         if ( requesttype == 0x01 )
138                         {   // For Control read transfer, we have to copy the read data from pIo_buf to pdata.
139                                 _rtw_memcpy( pdata, pIo_buf,  len );
140                         }
141                 }
142                 else { // error cases
143                         DBG_8723A("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n"
144                                 , value,(requesttype == 0x01)?"read":"write" , len, status, *(u32*)pdata, vendorreq_times);
145
146                         if (status < 0) {
147                                 if(status == (-ESHUTDOWN)       || status == -ENODEV    )
148                                 {
149                                         padapter->bSurpriseRemoved = _TRUE;
150                                 } else {
151                                         #ifdef DBG_CONFIG_ERROR_DETECT
152                                         {
153                                                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
154                                                 pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
155                                         }
156                                         #endif
157                                 }
158                         }
159                         else // status != len && status >= 0
160                         {
161                                 if(status > 0) {
162                                         if ( requesttype == 0x01 )
163                                         {   // For Control read transfer, we have to copy the read data from pIo_buf to pdata.
164                                                 _rtw_memcpy( pdata, pIo_buf,  len );
165                                         }
166                                 }
167                         }
168
169                         if(rtw_inc_and_chk_continual_urb_error(pdvobjpriv) == _TRUE ){
170                                 padapter->bSurpriseRemoved = _TRUE;
171                                 break;
172                         }
173
174                 }
175
176                 // firmware download is checksumed, don't retry
177                 if( (value >= FW_8723A_START_ADDRESS && value <= FW_8723A_END_ADDRESS) || status == len )
178                         break;
179
180         }
181
182         // release IO memory used by vendorreq
183         #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
184         rtw_mfree(tmp_buf, tmp_buflen);
185         #endif
186
187 release_mutex:
188         #ifdef CONFIG_USB_VENDOR_REQ_MUTEX
189         _exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL);
190         #endif
191 exit:
192         return status;
193
194 }
195
196 static u8 usb_read8(struct intf_hdl *pintfhdl, u32 addr)
197 {
198         u8 request;
199         u8 requesttype;
200         u16 wvalue;
201         u16 index;
202         u16 len;
203         u8 data=0;
204
205         _func_enter_;
206
207         request = 0x05;
208         requesttype = 0x01;//read_in
209         index = 0;//n/a
210
211         wvalue = (u16)(addr&0x0000ffff);
212         len = 1;
213
214         usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
215
216         _func_exit_;
217
218         return data;
219
220 }
221
222 static u16 usb_read16(struct intf_hdl *pintfhdl, u32 addr)
223 {
224         u8 request;
225         u8 requesttype;
226         u16 wvalue;
227         u16 index;
228         u16 len;
229         u16 data=0;
230
231         _func_enter_;
232
233         request = 0x05;
234         requesttype = 0x01;//read_in
235         index = 0;//n/a
236
237         wvalue = (u16)(addr&0x0000ffff);
238         len = 2;
239
240         usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
241
242         _func_exit_;
243
244         return data;
245
246 }
247
248 static u32 usb_read32(struct intf_hdl *pintfhdl, u32 addr)
249 {
250         u8 request;
251         u8 requesttype;
252         u16 wvalue;
253         u16 index;
254         u16 len;
255         u32 data=0;
256
257         _func_enter_;
258
259         request = 0x05;
260         requesttype = 0x01;//read_in
261         index = 0;//n/a
262
263         wvalue = (u16)(addr&0x0000ffff);
264         len = 4;
265
266         usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
267
268         _func_exit_;
269
270         return data;
271
272 }
273
274 static int usb_write8(struct intf_hdl *pintfhdl, u32 addr, u8 val)
275 {
276         u8 request;
277         u8 requesttype;
278         u16 wvalue;
279         u16 index;
280         u16 len;
281         u8 data;
282         int ret;
283
284         _func_enter_;
285
286         request = 0x05;
287         requesttype = 0x00;//write_out
288         index = 0;//n/a
289
290         wvalue = (u16)(addr&0x0000ffff);
291         len = 1;
292
293         data = val;
294
295          ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
296
297         _func_exit_;
298
299         return ret;
300
301 }
302
303 static int usb_write16(struct intf_hdl *pintfhdl, u32 addr, u16 val)
304 {
305         u8 request;
306         u8 requesttype;
307         u16 wvalue;
308         u16 index;
309         u16 len;
310         u16 data;
311         int ret;
312
313         _func_enter_;
314
315         request = 0x05;
316         requesttype = 0x00;//write_out
317         index = 0;//n/a
318
319         wvalue = (u16)(addr&0x0000ffff);
320         len = 2;
321
322         data = val;
323
324         ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
325
326         _func_exit_;
327
328         return ret;
329
330 }
331
332 static int usb_write32(struct intf_hdl *pintfhdl, u32 addr, u32 val)
333 {
334         u8 request;
335         u8 requesttype;
336         u16 wvalue;
337         u16 index;
338         u16 len;
339         u32 data;
340         int ret;
341
342         _func_enter_;
343
344         request = 0x05;
345         requesttype = 0x00;//write_out
346         index = 0;//n/a
347
348         wvalue = (u16)(addr&0x0000ffff);
349         len = 4;
350         data = val;
351
352
353         ret =usbctrl_vendorreq(pintfhdl, request, wvalue, index, &data, len, requesttype);
354
355         _func_exit_;
356
357         return ret;
358
359 }
360
361 static int usb_writeN(struct intf_hdl *pintfhdl, u32 addr, u32 length, u8 *pdata)
362 {
363         u8 request;
364         u8 requesttype;
365         u16 wvalue;
366         u16 index;
367         u16 len;
368         u8 buf[VENDOR_CMD_MAX_DATA_LEN]={0};
369         int ret;
370
371         _func_enter_;
372
373         request = 0x05;
374         requesttype = 0x00;//write_out
375         index = 0;//n/a
376
377         wvalue = (u16)(addr&0x0000ffff);
378         len = length;
379          _rtw_memcpy(buf, pdata, len );
380
381         ret = usbctrl_vendorreq(pintfhdl, request, wvalue, index, buf, len, requesttype);
382
383         _func_exit_;
384
385         return ret;
386
387 }
388
389 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
390 #if 0
391 /**
392 * Log the Interrupt value and update counter no matter STA is associated or not. It is
393 * implemented for FPGA verification stage because we need to now whether the current FPGA
394 * platform is alive
395 *
396 * \param pAdapter                       The adapter context for this minoport
397 * \param        IsrContent              The ISR value read from hardware in MPISR
398 *
399 * We sholud remove this function later because DDK suggest not to executing too many
400 * operations in MPISR
401 */
402 VOID
403 LogInterruptHistory8723AU(
404         PADAPTER                        Adapter
405 )
406 {
407         HAL_DATA_TYPE   *pHalData=GET_HAL_DATA(Adapter);
408
409 //      if(pHalData->IntArray[0] & IMR_COMDOK)
410 //              pHalData->InterruptLog.nIMR_COMDOK++;
411         if(pHalData->IntArray[0] & UHIMR_VODOK)
412         {
413                 pHalData->InterruptLog.nIMR_VODOK++;
414                 DBG_8723A("UHIMR_VODOK %d \n", pHalData->InterruptLog.nIMR_VODOK);
415         }
416         if(pHalData->IntArray[0] & UHIMR_VIDOK)
417         {
418                 pHalData->InterruptLog.nIMR_VIDOK++;
419                 DBG_8723A("UHIMR_VIDOK %d\n", pHalData->InterruptLog.nIMR_VIDOK);
420         }
421         if(pHalData->IntArray[0] & UHIMR_MGNTDOK)
422         {
423                 pHalData->InterruptLog.nIMR_MGNTDOK++;
424                 DBG_8723A("UHIMR_MGNTDOK %d\n", pHalData->InterruptLog.nIMR_MGNTDOK);
425         }
426         if(pHalData->IntArray[0] & UHIMR_BEDOK)
427         {
428                 pHalData->InterruptLog.nIMR_BEDOK++;
429                 DBG_8723A("UHIMR_BEDOK %d\n", pHalData->InterruptLog.nIMR_BEDOK);
430         }
431         if(pHalData->IntArray[0] & UHIMR_BKDOK)
432         {
433                 pHalData->InterruptLog.nIMR_BKDOK++;
434                 DBG_8723A("UHIMR_BKDOK %d\n", pHalData->InterruptLog.nIMR_BKDOK);
435         }
436         if(pHalData->IntArray[0] & UHIMR_ROK)
437         {
438                 pHalData->InterruptLog.nIMR_ROK++;
439                 DBG_8723A("UHIMR_ROK %d\n", pHalData->InterruptLog.nIMR_ROK);
440         }
441
442         if(pHalData->IntArray[0] & UHIMR_TXBCNOK)
443         {
444                 pHalData->InterruptLog.nIMR_TBDOK++;
445                 DBG_8723A("UHIMR_TXBCNOK %d\n", pHalData->InterruptLog.nIMR_TBDOK);
446         }
447         if(pHalData->IntArray[0] & UHIMR_BCNDOK0)
448         {
449                 pHalData->InterruptLog.nIMR_BDOK++;
450                 DBG_8723A("UHIMR_BCNDOK0 %d\n", pHalData->InterruptLog.nIMR_BDOK);
451         }
452         if(pHalData->IntArray[0] & UHIMR_C2HCMD)
453         {
454                 pHalData->InterruptLog.nIMR_C2HCMD++;
455                 DBG_8723A("UHIMR_C2HCMD %d\n", pHalData->InterruptLog.nIMR_C2HCMD);
456         }
457         if(pHalData->IntArray[0] & UHIMR_CPWM)
458         {
459                 pHalData->InterruptLog.nIMR_C2HCMD++;
460                 DBG_8723A("UHIMR_CPWM %d\n", pHalData->InterruptLog.nIMR_CPWM);
461         }
462
463 //      if(pHalData->IntArray[0] & IMR_RXCMDOK)
464 //              pHalData->InterruptLog.nIMR_RCOK++;
465         if(pHalData->IntArray[0] & UHIMR_RDU)
466         {
467                 pHalData->InterruptLog.nIMR_RDU++;
468                 DBG_8723A("UHIMR_RDU %d\n", pHalData->InterruptLog.nIMR_RDU);
469         }
470
471         if(pHalData->IntArray[1] & UHIMR_RXFOVW)
472         {
473                 pHalData->InterruptLog.nIMR_RXFOVW++;
474                 DBG_8723A("UHIMR_RXFOVW %d\n", pHalData->InterruptLog.nIMR_RXFOVW);
475         }
476
477
478 }
479 #endif
480 //
481 // Description:
482 //      Recognize the interrupt content by reading the interrupt register or content and masking interrupt mask (IMR)
483 //      if it is our NIC's interrupt. After recognizing, we may clear the all interrupts (ISR).
484 // Arguments:
485 //      [in] Adapter -
486 //              The adapter context.
487 //      [in] pContent -
488 //              Under PCI interface, this field is ignord.
489 //              Under USB interface, the content is the interrupt content pointer.
490 //              Under SDIO interface, this is the interrupt type which is Local interrupt or system interrupt.
491 //      [in] ContentLen -
492 //              The length in byte of pContent.
493 // Return:
494 //      If any interrupt matches the mask (IMR), return TRUE, and return FALSE otherwise.
495 //
496 bool
497 InterruptRecognized8723AU(
498         IN      PADAPTER                        Adapter,
499         IN      PVOID                           pContent,
500         IN      u32                             ContentLen
501 )
502 {
503         HAL_DATA_TYPE   *pHalData=GET_HAL_DATA(Adapter);
504         u8 *                    buffer = (u8 *)pContent;
505 //      RT_PRINT_DATA(COMP_RECV, DBG_LOUD, ("InterruptRecognized8723AU Interrupt buffer \n"), buffer, MAX_RECEIVE_INTERRUPT_BUFFER_SIZE(Adapter));
506
507         _rtw_memcpy(&(pHalData->IntArray[0]), &(buffer[USB_INTR_CONTENT_HISR_OFFSET]), 4);
508 //      PlatformMoveMemory(&(pHalData->IntArray[0]), &(buffer[USB_INTR_CONTENT_HISR_OFFSET]), sizeof(u4Byte));
509 //      DBG_8723A("InterruptRecognized8723AU HISR = 0x%x HIMR = 0x%x\n", pHalData->IntArray[0],pHalData->IntrMask[0]);
510         pHalData->IntArray[0] &= pHalData->IntrMask[0];
511
512         //For HISR extension. Added by tynli. 2009.10.07.
513         _rtw_memcpy(&(pHalData->IntArray[1]), &(buffer[USB_INTR_CONTENT_HISRE_OFFSET]), 4);
514 //      PlatformMoveMemory(&(pHalData->IntArray[1]), &(buffer[USB_INTR_CONTENT_HISRE_OFFSET]), sizeof(u4Byte));
515 //      DBG_8723A("InterruptRecognized8192CUsb HISRE = 0x%x HIMRE = 0x%x\n", pHalData->IntArray[1], pHalData->IntrMask[1]);
516         pHalData->IntArray[1] &= pHalData->IntrMask[1];
517
518         // We sholud remove this function later because DDK suggest not to executing too many operations in MPISR
519 //      if(pHalData->IntArray[0] != 0)
520 //              LogInterruptHistory8723AU(Adapter);
521
522         {
523                 struct reportpwrstate_parm report;
524                 _rtw_memcpy(&report.state, &(buffer[USB_INTR_CPWM_OFFSET]), 1);
525 #ifdef CONFIG_LPS_LCLK
526                 if( ((pHalData->IntArray[0])&UHIMR_CPWM)){
527 //                      DBG_8723A("%s HIMR=0x%x\n",__func__,pHalData->IntArray[0]);
528                         //cpwm_int_hdl(Adapter, &report);
529                         _set_workitem(&Adapter->pwrctrlpriv.cpwm_event);
530                         pHalData->IntArray[0]&= ~UHIMR_CPWM;
531 //                      DBG_8723A("%s HIMR=0x%x\n",__func__,pHalData->IntArray[0]);
532                 }
533 #endif
534         }
535         return (((pHalData->IntArray[0])&pHalData->IntrMask[0])!=0 ||
536                 ((pHalData->IntArray[1])&pHalData->IntrMask[1])!=0);
537
538 }
539
540
541 static void usb_read_interrupt_complete(struct urb *purb, struct pt_regs *regs)
542 {
543         int     err;
544         PADAPTER padapter = (PADAPTER)purb->context;
545
546
547         if(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel)
548         {
549                 DBG_8723A("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
550                 __FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel);
551                 return;
552         }
553
554         if (purb->status == 0)//SUCCESS
555         {
556                 struct c2h_evt_hdr *c2h_evt = (struct c2h_evt_hdr *)purb->transfer_buffer;
557
558                 if (purb->actual_length > USB_INTR_CONTENT_LENGTH) {
559                         DBG_8723A("usb_read_interrupt_complete: purb->actual_length > USB_INTR_CONTENT_LENGTH\n");
560                         goto urb_submit;
561                 }
562
563                 InterruptRecognized8723AU(padapter, purb->transfer_buffer, purb->actual_length);
564
565                 if (c2h_evt_exist(c2h_evt)) {
566                         if (0)
567                                 DBG_8723A("%s C2H == %d\n", __func__, c2h_evt->id);
568                         if (c2h_id_filter_ccx_8723a(c2h_evt->id)) {
569                                 /* Handle CCX report here */
570                                 handle_txrpt_ccx_8723a(padapter, (void *)(c2h_evt->payload));
571                                 /* Replace with special pointer to trigger c2h_evt_clear */
572                                 if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)&padapter->evtpriv) != _SUCCESS)
573                                         DBG_8723A("%s rtw_cbuf_push fail\n", __func__);
574                                 _set_workitem(&padapter->evtpriv.c2h_wk);
575                         } else if ((c2h_evt = (struct c2h_evt_hdr *)rtw_malloc(16)) != NULL) {
576                                 _rtw_memcpy(c2h_evt, purb->transfer_buffer, 16);
577                                 if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)c2h_evt) != _SUCCESS)
578                                         DBG_8723A("%s rtw_cbuf_push fail\n", __func__);
579                                 _set_workitem(&padapter->evtpriv.c2h_wk);
580                         } else {
581                                 /* Error handling for malloc fail */
582                                 if (rtw_cbuf_push(padapter->evtpriv.c2h_queue, (void*)NULL) != _SUCCESS)
583                                         DBG_8723A("%s rtw_cbuf_push fail\n", __func__);
584                                 _set_workitem(&padapter->evtpriv.c2h_wk);
585                         }
586                 }
587
588 urb_submit:
589                 err = usb_submit_urb(purb, GFP_ATOMIC);
590                 if ((err) && (err != (-EPERM)))
591                 {
592                         DBG_8723A("cannot submit interrupt in-token(err = 0x%08x),urb_status = %d\n",err, purb->status);
593                 }
594         }
595         else
596         {
597                 DBG_8723A("###=> usb_read_interrupt_complete => urb status(%d)\n", purb->status);
598
599                 switch (purb->status)
600                 {
601                         case -EINVAL:
602                         case -EPIPE:
603                         case -ENODEV:
604                         case -ESHUTDOWN:
605                                 //padapter->bSurpriseRemoved = _TRUE;
606                                 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete:bSurpriseRemoved=TRUE\n"));
607                         case -ENOENT:
608                                 padapter->bDriverStopped = _TRUE;
609                                 RT_TRACE(_module_hci_ops_os_c_, _drv_err_, ("usb_read_port_complete:bDriverStopped=TRUE\n"));
610                                 break;
611                         case -EPROTO:
612                                 break;
613                         case -EINPROGRESS:
614                                 DBG_8723A("ERROR: URB IS IN PROGRESS!/n");
615                                 break;
616                         default:
617                                 break;
618                 }
619         }
620 }
621
622 static u32 usb_read_interrupt(struct intf_hdl *pintfhdl, u32 addr)
623 {
624         int     err;
625         unsigned int pipe;
626         u32     ret = _SUCCESS;
627         _adapter                        *adapter = pintfhdl->padapter;
628         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
629         struct recv_priv        *precvpriv = &adapter->recvpriv;
630         struct usb_device       *pusbd = pdvobj->pusbdev;
631
632 _func_enter_;
633
634         //translate DMA FIFO addr to pipehandle
635         pipe = ffaddr2pipehdl(pdvobj, addr);
636
637         usb_fill_int_urb(precvpriv->int_in_urb, pusbd, pipe,
638                                         precvpriv->int_in_buf,
639                                         USB_INTR_CONTENT_LENGTH,
640                                         usb_read_interrupt_complete,
641                                         adapter,
642                                         1);
643
644         err = usb_submit_urb(precvpriv->int_in_urb, GFP_ATOMIC);
645         if((err) && (err != (-EPERM)))
646         {
647                 DBG_8723A("cannot submit interrupt in-token(err = 0x%08x),urb_status = %d\n",err, precvpriv->int_in_urb->status);
648                 ret = _FAIL;
649         }
650
651 _func_exit_;
652
653         return ret;
654 }
655 #endif
656
657 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
658 static int recvbuf2recvframe(_adapter *padapter, struct recv_buf *precvbuf)
659 {
660         u8      *pbuf;
661         u8      shift_sz = 0;
662         u16     pkt_cnt, drvinfo_sz;
663         u32     pkt_offset, skb_len, alloc_sz;
664         s32     transfer_len;
665         struct recv_stat        *prxstat;
666         struct phy_stat *pphy_info = NULL;
667         _pkt                            *pkt_copy = NULL;
668         union recv_frame        *precvframe = NULL;
669         struct rx_pkt_attrib    *pattrib = NULL;
670         HAL_DATA_TYPE           *pHalData = GET_HAL_DATA(padapter);
671         struct recv_priv        *precvpriv = &padapter->recvpriv;
672         _queue                  *pfree_recv_queue = &precvpriv->free_recv_queue;
673
674
675         transfer_len = (s32)precvbuf->transfer_len;
676         pbuf = precvbuf->pbuf;
677
678         prxstat = (struct recv_stat *)pbuf;
679         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
680
681 #if 0 //temp remove when disable usb rx aggregation
682         if((pkt_cnt > 10) || (pkt_cnt < 1) || (transfer_len<RXDESC_SIZE) ||(pkt_len<=0))
683         {
684                 return _FAIL;
685         }
686 #endif
687
688         do{
689                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
690                          ("recvbuf2recvframe: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
691                           prxstat->rxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4));
692
693                 prxstat = (struct recv_stat *)pbuf;
694
695                 precvframe = rtw_alloc_recvframe(pfree_recv_queue);
696                 if(precvframe==NULL)
697                 {
698                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: precvframe==NULL\n"));
699                         DBG_8723A("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__, __LINE__);
700                         goto _exit_recvbuf2recvframe;
701                 }
702
703                 _rtw_init_listhead(&precvframe->u.hdr.list);
704                 precvframe->u.hdr.precvbuf = NULL;      //can't access the precvbuf for new arch.
705                 precvframe->u.hdr.len=0;
706
707 //              rtl8192c_query_rx_desc_status(precvframe, prxstat);
708                 update_recvframe_attrib(precvframe, prxstat);
709
710                 pattrib = &precvframe->u.hdr.attrib;
711
712                 if(pattrib->crc_err){
713                         DBG_8723A("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
714                         rtw_free_recvframe(precvframe, pfree_recv_queue);
715                         goto _exit_recvbuf2recvframe;
716                 }
717
718                 pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
719
720                 if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len))
721                 {
722                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("recvbuf2recvframe: pkt_len<=0\n"));
723                         DBG_8723A("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__);
724                         rtw_free_recvframe(precvframe, pfree_recv_queue);
725                         goto _exit_recvbuf2recvframe;
726                 }
727
728                 //      Modified by Albert 20101213
729                 //      For 8 bytes IP header alignment.
730                 if (pattrib->qos)       //      Qos data, wireless lan header length is 26
731                 {
732                         shift_sz = 6;
733                 }
734                 else
735                 {
736                         shift_sz = 0;
737                 }
738
739                 skb_len = pattrib->pkt_len;
740
741                 // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
742                 // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
743                 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
744                         //alloc_sz = 1664;      //1664 is 128 alignment.
745                         if(skb_len <= 1650)
746                                 alloc_sz = 1664;
747                         else
748                                 alloc_sz = skb_len + 14;
749                 }
750                 else {
751                         alloc_sz = skb_len;
752                         //      6 is for IP header 8 bytes alignment in QoS packet case.
753                         //      8 is for skb->data 4 bytes alignment.
754                         alloc_sz += 14;
755                 }
756
757 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
758                 pkt_copy = dev_alloc_skb(alloc_sz);
759 #else
760                 pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
761 #endif
762                 if(pkt_copy)
763                 {
764                         pkt_copy->dev = padapter->pnetdev;
765                         precvframe->u.hdr.pkt = pkt_copy;
766                         precvframe->u.hdr.rx_head = pkt_copy->data;
767                         precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
768                         skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
769                         skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
770                         _rtw_memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
771                         precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
772                 }
773                 else
774                 {
775                         DBG_8723A("recvbuf2recvframe:can not allocate memory for skb copy\n");
776                         //precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC);
777                         //precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pbuf;
778                         //precvframe->u.hdr.rx_end = pbuf + (pkt_offset>1612?pkt_offset:1612);
779
780                         precvframe->u.hdr.pkt = NULL;
781                         rtw_free_recvframe(precvframe, pfree_recv_queue);
782
783                         goto _exit_recvbuf2recvframe;
784                 }
785
786                 recvframe_put(precvframe, skb_len);
787                 //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
788
789                 if (pattrib->physt)
790                 {
791                         pphy_info = (struct phy_stat*)(pbuf + RXDESC_OFFSET);
792                         update_recvframe_phyinfo(precvframe, pphy_info);
793                 }
794
795 #ifdef CONFIG_USB_RX_AGGREGATION
796                 switch(pHalData->UsbRxAggMode)
797                 {
798                         case USB_RX_AGG_DMA:
799                         case USB_RX_AGG_MIX:
800                                 pkt_offset = (u16)_RND128(pkt_offset);
801                                 break;
802                                 case USB_RX_AGG_USB:
803                                 pkt_offset = (u16)_RND4(pkt_offset);
804                                 break;
805                         case USB_RX_AGG_DISABLE:
806                         default:
807                                 break;
808                 }
809 #endif
810
811                 if(rtw_recv_entry(precvframe) != _SUCCESS)
812                 {
813                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
814                 }
815
816                 pkt_cnt--;
817                 transfer_len -= pkt_offset;
818                 pbuf += pkt_offset;
819                 precvframe = NULL;
820                 pkt_copy = NULL;
821
822                 if(transfer_len>0 && pkt_cnt==0)
823                         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
824
825         }while((transfer_len>0) && (pkt_cnt>0));
826
827 _exit_recvbuf2recvframe:
828
829         return _SUCCESS;
830 }
831
832 void rtl8192cu_recv_tasklet(void *priv)
833 {
834         struct recv_buf *precvbuf = NULL;
835         _adapter        *padapter = (_adapter*)priv;
836         struct recv_priv        *precvpriv = &padapter->recvpriv;
837
838         while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue)))
839         {
840                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
841                 {
842                         DBG_8723A("recv_tasklet => bDriverStopped or bSurpriseRemoved \n");
843
844                         break;
845                 }
846
847
848                 recvbuf2recvframe(padapter, precvbuf);
849
850                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
851         }
852
853 }
854
855 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
856 {
857         struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
858         _adapter                        *padapter =(_adapter *)precvbuf->adapter;
859         struct recv_priv        *precvpriv = &padapter->recvpriv;
860
861         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n"));
862
863         precvpriv->rx_pending_cnt --;
864
865         if(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel)
866         {
867                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved));
868
869                 goto exit;
870         }
871
872         if(purb->status==0)//SUCCESS
873         {
874                 if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE))
875                 {
876                         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n"));
877
878                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
879                 }
880                 else
881                 {
882                         rtw_reset_continual_urb_error(adapter_to_dvobj(padapter));
883
884                         precvbuf->transfer_len = purb->actual_length;
885
886                         //rtw_enqueue_rx_transfer_buffer(precvpriv, rx_transfer_buf);
887                         rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue);
888
889                         tasklet_schedule(&precvpriv->recv_tasklet);
890                 }
891         }
892         else
893         {
894                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status));
895
896                 DBG_8723A("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
897
898                 if(rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(padapter)) == _TRUE ){
899                         padapter->bSurpriseRemoved = _TRUE;
900                 }
901
902                 switch(purb->status) {
903                         case -EINVAL:
904                         case -EPIPE:
905                         case -ENODEV:
906                         case -ESHUTDOWN:
907                                 //padapter->bSurpriseRemoved=_TRUE;
908                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n"));
909                         case -ENOENT:
910                                 padapter->bDriverStopped=_TRUE;
911                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n"));
912                                 break;
913                         case -EPROTO:
914                         case -EOVERFLOW:
915                                 #ifdef DBG_CONFIG_ERROR_DETECT
916                                 {
917                                         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
918                                         pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
919                                 }
920                                 #endif
921                                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
922                                 break;
923                         case -EINPROGRESS:
924                                 DBG_8723A("ERROR: URB IS IN PROGRESS!/n");
925                                 break;
926                         default:
927                                 break;
928                 }
929
930         }
931
932 exit:
933
934 _func_exit_;
935
936 }
937
938 static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
939 {
940         int err;
941         unsigned int pipe;
942         u32 ret = _SUCCESS;
943         PURB purb = NULL;
944         struct recv_buf *precvbuf = (struct recv_buf *)rmem;
945         _adapter                *adapter = pintfhdl->padapter;
946         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
947         struct recv_priv        *precvpriv = &adapter->recvpriv;
948         struct usb_device       *pusbd = pdvobj->pusbdev;
949
950 _func_enter_;
951
952         if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)
953         {
954                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
955                 return _FAIL;
956         }
957
958         if(precvbuf !=NULL)
959         {
960                 rtl8192cu_init_recvbuf(adapter, precvbuf);
961
962                 if(precvbuf->pbuf)
963                 {
964                         precvpriv->rx_pending_cnt++;
965
966                         purb = precvbuf->purb;
967
968                         //translate DMA FIFO addr to pipehandle
969                         pipe = ffaddr2pipehdl(pdvobj, addr);
970
971                         usb_fill_bulk_urb(purb, pusbd, pipe,
972                                                 precvbuf->pbuf,
973                                                 MAX_RECVBUF_SZ,
974                                                 usb_read_port_complete,
975                                                 precvbuf);//context is precvbuf
976
977                         purb->transfer_dma = precvbuf->dma_transfer_addr;
978                         purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
979
980                         err = usb_submit_urb(purb, GFP_ATOMIC);
981                         if((err) && (err != (-EPERM)))
982                         {
983                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status));
984                                 DBG_8723A("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status);
985                                 ret = _FAIL;
986                         }
987
988                 }
989
990         }
991         else
992         {
993                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n"));
994                 ret = _FAIL;
995         }
996
997 _func_exit_;
998
999         return ret;
1000 }
1001 #else   // CONFIG_USE_USB_BUFFER_ALLOC_RX
1002 static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_stat *prxstat, struct phy_stat *pphy_info)
1003 {
1004         s32 ret=_SUCCESS;
1005 #ifdef CONFIG_CONCURRENT_MODE
1006         u8 *primary_myid, *secondary_myid, *paddr1;
1007         union recv_frame        *precvframe_if2 = NULL;
1008         _adapter *primary_padapter = precvframe->u.hdr.adapter;
1009         _adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
1010         struct recv_priv *precvpriv = &primary_padapter->recvpriv;
1011         _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
1012         u8      *pbuf = precvframe->u.hdr.rx_data;
1013
1014         if(!secondary_padapter)
1015                 return ret;
1016
1017         paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);
1018
1019         if(IS_MCAST(paddr1) == _FALSE)//unicast packets
1020         {
1021                 //primary_myid = myid(&primary_padapter->eeprompriv);
1022                 secondary_myid = myid(&secondary_padapter->eeprompriv);
1023
1024                 if(_rtw_memcmp(paddr1, secondary_myid, ETH_ALEN))
1025                 {
1026                         //change to secondary interface
1027                         precvframe->u.hdr.adapter = secondary_padapter;
1028                 }
1029
1030                 //ret = recv_entry(precvframe);
1031
1032         }
1033         else // Handle BC/MC Packets
1034         {
1035
1036                 u8 clone = _TRUE;
1037 #if 0
1038                 u8 type, subtype, *paddr2, *paddr3;
1039
1040                 type =  GetFrameType(pbuf);
1041                 subtype = GetFrameSubType(pbuf); //bit(7)~bit(2)
1042
1043                 switch (type)
1044                 {
1045                         case WIFI_MGT_TYPE: //Handle BC/MC mgnt Packets
1046                                 if(subtype == WIFI_BEACON)
1047                                 {
1048                                         paddr3 = GetAddr3Ptr(precvframe->u.hdr.rx_data);
1049
1050                                         if (check_fwstate(&secondary_padapter->mlmepriv, _FW_LINKED) &&
1051                                                 _rtw_memcmp(paddr3, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN))
1052                                         {
1053                                                 //change to secondary interface
1054                                                 precvframe->u.hdr.adapter = secondary_padapter;
1055                                                 clone = _FALSE;
1056                                         }
1057
1058                                         if(check_fwstate(&primary_padapter->mlmepriv, _FW_LINKED) &&
1059                                                 _rtw_memcmp(paddr3, get_bssid(&primary_padapter->mlmepriv), ETH_ALEN))
1060                                         {
1061                                                 if(clone==_FALSE)
1062                                                 {
1063                                                         clone = _TRUE;
1064                                                 }
1065                                                 else
1066                                                 {
1067                                                         clone = _FALSE;
1068                                                 }
1069
1070                                                 precvframe->u.hdr.adapter = primary_padapter;
1071                                         }
1072
1073                                         if(check_fwstate(&primary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) ||
1074                                                 check_fwstate(&secondary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING))
1075                                         {
1076                                                 clone = _TRUE;
1077                                                 precvframe->u.hdr.adapter = primary_padapter;
1078                                         }
1079
1080                                 }
1081                                 else if(subtype == WIFI_PROBEREQ)
1082                                 {
1083                                         //probe req frame is only for interface2
1084                                         //change to secondary interface
1085                                         precvframe->u.hdr.adapter = secondary_padapter;
1086                                         clone = _FALSE;
1087                                 }
1088                                 break;
1089                         case WIFI_CTRL_TYPE: // Handle BC/MC ctrl Packets
1090
1091                                 break;
1092                         case WIFI_DATA_TYPE: //Handle BC/MC data Packets
1093                                         //Notes: AP MODE never rx BC/MC data packets
1094
1095                                 paddr2 = GetAddr2Ptr(precvframe->u.hdr.rx_data);
1096
1097                                 if(_rtw_memcmp(paddr2, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN))
1098                                 {
1099                                         //change to secondary interface
1100                                         precvframe->u.hdr.adapter = secondary_padapter;
1101                                         clone = _FALSE;
1102                                 }
1103
1104                                 break;
1105                         default:
1106
1107                                 break;
1108                 }
1109 #endif
1110
1111                 if(_TRUE == clone)
1112                 {
1113                         //clone/copy to if2
1114                         u8 shift_sz = 0;
1115                         u32 alloc_sz, skb_len;
1116                         _pkt     *pkt_copy = NULL;
1117                         struct rx_pkt_attrib *pattrib = NULL;
1118
1119                         precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
1120                         if(precvframe_if2)
1121                         {
1122                                 precvframe_if2->u.hdr.adapter = secondary_padapter;
1123
1124                                 _rtw_init_listhead(&precvframe_if2->u.hdr.list);
1125                                 precvframe_if2->u.hdr.precvbuf = NULL;  //can't access the precvbuf for new arch.
1126                                 precvframe_if2->u.hdr.len=0;
1127
1128                                 _rtw_memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
1129
1130                                 pattrib = &precvframe_if2->u.hdr.attrib;
1131
1132                                 //      Modified by Albert 20101213
1133                                 //      For 8 bytes IP header alignment.
1134                                 if (pattrib->qos)       //      Qos data, wireless lan header length is 26
1135                                 {
1136                                         shift_sz = 6;
1137                                 }
1138                                 else
1139                                 {
1140                                         shift_sz = 0;
1141                                 }
1142
1143                                 skb_len = pattrib->pkt_len;
1144
1145                                 // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
1146                                 // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
1147                                 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
1148                                         //alloc_sz = 1664;      //1664 is 128 alignment.
1149                                         if(skb_len <= 1650)
1150                                                 alloc_sz = 1664;
1151                                         else
1152                                                 alloc_sz = skb_len + 14;
1153                                 }
1154                                 else {
1155                                         alloc_sz = skb_len;
1156                                         //      6 is for IP header 8 bytes alignment in QoS packet case.
1157                                         //      8 is for skb->data 4 bytes alignment.
1158                                         alloc_sz += 14;
1159                                 }
1160
1161 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
1162                                 pkt_copy = dev_alloc_skb(alloc_sz);
1163 #else
1164                                 pkt_copy = netdev_alloc_skb(secondary_padapter->pnetdev, alloc_sz);
1165 #endif
1166                                 if(pkt_copy)
1167                                 {
1168                                         pkt_copy->dev = secondary_padapter->pnetdev;
1169                                         precvframe_if2->u.hdr.pkt = pkt_copy;
1170                                         precvframe_if2->u.hdr.rx_head = pkt_copy->data;
1171                                         precvframe_if2->u.hdr.rx_end = pkt_copy->data + alloc_sz;
1172                                         skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
1173                                         skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
1174                                         _rtw_memcpy(pkt_copy->data, pbuf, skb_len);
1175                                         precvframe_if2->u.hdr.rx_data = precvframe_if2->u.hdr.rx_tail = pkt_copy->data;
1176
1177
1178                                         recvframe_put(precvframe_if2, skb_len);
1179                                         //recvframe_pull(precvframe_if2, drvinfo_sz + RXDESC_SIZE);
1180                                         if(pphy_info)
1181                                         update_recvframe_phyinfo(precvframe_if2, pphy_info);
1182                                         //rtl8192c_translate_rx_signal_stuff(precvframe_if2, pphy_info);
1183
1184                                         ret = rtw_recv_entry(precvframe_if2);
1185
1186                                 } else {
1187                                         rtw_free_recvframe(precvframe_if2, pfree_recv_queue);
1188                                         DBG_8723A("%s()-%d: alloc_skb() failed!\n", __FUNCTION__, __LINE__);
1189                                 }
1190
1191                         }
1192
1193                 }
1194
1195         }
1196
1197         ret = rtw_recv_entry(precvframe);
1198
1199 #endif
1200
1201         return ret;
1202
1203 }
1204
1205 static int recvbuf2recvframe(_adapter *padapter, _pkt *pskb)
1206 {
1207         u8      *pbuf;
1208         u8      shift_sz = 0;
1209         u16     pkt_cnt;
1210         u32     pkt_offset, skb_len, alloc_sz;
1211         s32     transfer_len;
1212         struct recv_stat        *prxstat;
1213         struct phy_stat *pphy_info = NULL;
1214         _pkt                            *pkt_copy = NULL;
1215         union recv_frame        *precvframe = NULL;
1216         struct rx_pkt_attrib    *pattrib = NULL;
1217         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
1218         struct recv_priv        *precvpriv = &padapter->recvpriv;
1219         _queue                  *pfree_recv_queue = &precvpriv->free_recv_queue;
1220
1221
1222         transfer_len = (s32)pskb->len;
1223         pbuf = pskb->data;
1224
1225         prxstat = (struct recv_stat *)pbuf;
1226         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
1227
1228 #if 0 //temp remove when disable usb rx aggregation
1229         if((pkt_cnt > 10) || (pkt_cnt < 1) || (transfer_len<RXDESC_SIZE) ||(pkt_len<=0))
1230         {
1231                 return _FAIL;
1232         }
1233 #endif
1234
1235         do{
1236                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1237                          ("recvbuf2recvframe: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
1238                           prxstat->rxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4));
1239
1240                 prxstat = (struct recv_stat *)pbuf;
1241
1242                 precvframe = rtw_alloc_recvframe(pfree_recv_queue);
1243                 if(precvframe==NULL)
1244                 {
1245                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: precvframe==NULL\n"));
1246                         DBG_8723A("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__, __LINE__);
1247                         goto _exit_recvbuf2recvframe;
1248                 }
1249
1250                 _rtw_init_listhead(&precvframe->u.hdr.list);
1251                 precvframe->u.hdr.precvbuf = NULL;      //can't access the precvbuf for new arch.
1252                 precvframe->u.hdr.len=0;
1253
1254 //              rtl8192c_query_rx_desc_status(precvframe, prxstat);
1255                 update_recvframe_attrib(precvframe, prxstat);
1256
1257                 pattrib = &precvframe->u.hdr.attrib;
1258
1259                 if(pattrib->crc_err){
1260                         DBG_8723A("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
1261                         rtw_free_recvframe(precvframe, pfree_recv_queue);
1262                         goto _exit_recvbuf2recvframe;
1263                 }
1264
1265                 pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
1266
1267                 if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len))
1268                 {
1269                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("recvbuf2recvframe: pkt_len<=0\n"));
1270                         DBG_8723A("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__);
1271                         rtw_free_recvframe(precvframe, pfree_recv_queue);
1272                         goto _exit_recvbuf2recvframe;
1273                 }
1274
1275                 //      Modified by Albert 20101213
1276                 //      For 8 bytes IP header alignment.
1277                 if (pattrib->qos)       //      Qos data, wireless lan header length is 26
1278                 {
1279                         shift_sz = 6;
1280                 }
1281                 else
1282                 {
1283                         shift_sz = 0;
1284                 }
1285
1286                 skb_len = pattrib->pkt_len;
1287
1288                 // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
1289                 // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
1290                 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
1291                         //alloc_sz = 1664;      //1664 is 128 alignment.
1292                         if(skb_len <= 1650)
1293                                 alloc_sz = 1664;
1294                         else
1295                                 alloc_sz = skb_len + 14;
1296                 }
1297                 else {
1298                         alloc_sz = skb_len;
1299                         //      6 is for IP header 8 bytes alignment in QoS packet case.
1300                         //      8 is for skb->data 4 bytes alignment.
1301                         alloc_sz += 14;
1302                 }
1303
1304 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
1305                 pkt_copy = dev_alloc_skb(alloc_sz);
1306 #else
1307                 pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
1308 #endif
1309                 if(pkt_copy)
1310                 {
1311                         pkt_copy->dev = padapter->pnetdev;
1312                         precvframe->u.hdr.pkt = pkt_copy;
1313                         precvframe->u.hdr.rx_head = pkt_copy->data;
1314                         precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
1315                         skb_reserve( pkt_copy, 8 - ((SIZE_PTR)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
1316                         skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
1317                         _rtw_memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
1318                         precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
1319                 }
1320                 else
1321                 {
1322                         if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
1323                         {
1324                                 DBG_8723A("recvbuf2recvframe: alloc_skb fail , drop frag frame \n");
1325                                 rtw_free_recvframe(precvframe, pfree_recv_queue);
1326                                 goto _exit_recvbuf2recvframe;
1327                         }
1328
1329                         precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC);
1330                         if(precvframe->u.hdr.pkt)
1331                         {
1332                                 precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail
1333                                         = pbuf+ pattrib->drvinfo_sz + RXDESC_SIZE;
1334                                 precvframe->u.hdr.rx_end =  pbuf +pattrib->drvinfo_sz + RXDESC_SIZE+ alloc_sz;
1335                         }
1336                         else
1337                         {
1338                                 DBG_8723A("recvbuf2recvframe: skb_clone fail\n");
1339                                 rtw_free_recvframe(precvframe, pfree_recv_queue);
1340                                 goto _exit_recvbuf2recvframe;
1341                         }
1342
1343                 }
1344
1345                 recvframe_put(precvframe, skb_len);
1346                 //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
1347
1348                 if (pattrib->physt)
1349                 {
1350                         pphy_info = (struct phy_stat*)(pbuf + RXDESC_OFFSET);
1351                         update_recvframe_phyinfo(precvframe, pphy_info);
1352                 }
1353
1354 #ifdef CONFIG_USB_RX_AGGREGATION
1355                 switch(pHalData->UsbRxAggMode)
1356                 {
1357                         case USB_RX_AGG_DMA:
1358                         case USB_RX_AGG_MIX:
1359                                 pkt_offset = (u16)_RND128(pkt_offset);
1360                                 break;
1361                                 case USB_RX_AGG_USB:
1362                                 pkt_offset = (u16)_RND4(pkt_offset);
1363                                 break;
1364                         case USB_RX_AGG_DISABLE:
1365                         default:
1366                                 break;
1367                 }
1368 #endif
1369
1370 #ifdef CONFIG_CONCURRENT_MODE
1371                 if(pre_recv_entry(precvframe, prxstat, pphy_info) != _SUCCESS)
1372                 {
1373                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
1374                 }
1375 #else
1376                 if(rtw_recv_entry(precvframe) != _SUCCESS)
1377                 {
1378                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
1379                 }
1380 #endif
1381
1382                 pkt_cnt--;
1383                 transfer_len -= pkt_offset;
1384                 pbuf += pkt_offset;
1385                 precvframe = NULL;
1386                 pkt_copy = NULL;
1387
1388                 if(transfer_len>0 && pkt_cnt==0)
1389                         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
1390
1391         }while((transfer_len>0) && (pkt_cnt>0));
1392
1393 _exit_recvbuf2recvframe:
1394
1395         return _SUCCESS;
1396 }
1397
1398 void rtl8192cu_recv_tasklet(void *priv)
1399 {
1400         _pkt                    *pskb;
1401         _adapter                *padapter = (_adapter*)priv;
1402         struct recv_priv        *precvpriv = &padapter->recvpriv;
1403
1404         while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue)))
1405         {
1406                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
1407                 {
1408                         DBG_8723A("recv_tasklet => bDriverStopped or bSurpriseRemoved \n");
1409                         dev_kfree_skb_any(pskb);
1410                         break;
1411                 }
1412
1413                 recvbuf2recvframe(padapter, pskb);
1414
1415 #ifdef CONFIG_PREALLOC_RECV_SKB
1416
1417                 skb_reset_tail_pointer(pskb);
1418
1419                 pskb->len = 0;
1420
1421                 skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
1422
1423 #else
1424                 dev_kfree_skb_any(pskb);
1425 #endif
1426
1427         }
1428
1429 }
1430
1431
1432 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
1433 {
1434         _irqL irqL;
1435         uint isevt, *pbuf;
1436         struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
1437         _adapter                        *padapter =(_adapter *)precvbuf->adapter;
1438         struct recv_priv        *precvpriv = &padapter->recvpriv;
1439
1440         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n"));
1441
1442         //_enter_critical(&precvpriv->lock, &irqL);
1443         //precvbuf->irp_pending=_FALSE;
1444         //precvpriv->rx_pending_cnt --;
1445         //_exit_critical(&precvpriv->lock, &irqL);
1446
1447         precvpriv->rx_pending_cnt --;
1448
1449         //if(precvpriv->rx_pending_cnt== 0)
1450         //{
1451         //      RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: rx_pending_cnt== 0, set allrxreturnevt!\n"));
1452         //      _rtw_up_sema(&precvpriv->allrxreturnevt);
1453         //}
1454
1455         if(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel)
1456         {
1457                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved));
1458
1459         #ifdef CONFIG_PREALLOC_RECV_SKB
1460                 precvbuf->reuse = _TRUE;
1461         #else
1462                 if(precvbuf->pskb){
1463                         DBG_8723A("==> free skb(%p)\n",precvbuf->pskb);
1464                         dev_kfree_skb_any(precvbuf->pskb);
1465                 }
1466         #endif
1467                 DBG_8723A("%s()-%d: RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
1468                 __FUNCTION__, __LINE__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel);
1469                 goto exit;
1470         }
1471
1472         if(purb->status==0)//SUCCESS
1473         {
1474                 if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE))
1475                 {
1476                         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n"));
1477                         precvbuf->reuse = _TRUE;
1478                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
1479                         DBG_8723A("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__);
1480                 }
1481                 else
1482                 {
1483                         rtw_reset_continual_urb_error(adapter_to_dvobj(padapter));
1484
1485                         precvbuf->transfer_len = purb->actual_length;
1486                         skb_put(precvbuf->pskb, purb->actual_length);
1487                         skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
1488
1489                         if (skb_queue_len(&precvpriv->rx_skb_queue)<=1)
1490                                 tasklet_schedule(&precvpriv->recv_tasklet);
1491
1492                         precvbuf->pskb = NULL;
1493                         precvbuf->reuse = _FALSE;
1494                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
1495                 }
1496         }
1497         else
1498         {
1499                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status));
1500
1501                 DBG_8723A("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
1502
1503                 if(rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(padapter)) == _TRUE ){
1504                         padapter->bSurpriseRemoved = _TRUE;
1505                 }
1506
1507                 switch(purb->status) {
1508                         case -EINVAL:
1509                         case -EPIPE:
1510                         case -ENODEV:
1511                         case -ESHUTDOWN:
1512                                 //padapter->bSurpriseRemoved=_TRUE;
1513                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n"));
1514                         case -ENOENT:
1515                                 padapter->bDriverStopped=_TRUE;
1516                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n"));
1517                                 break;
1518                         case -EPROTO:
1519                         case -EOVERFLOW:
1520                                 #ifdef DBG_CONFIG_ERROR_DETECT
1521                                 {
1522                                         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
1523                                         pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
1524                                 }
1525                                 #endif
1526                                 precvbuf->reuse = _TRUE;
1527                                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
1528                                 break;
1529                         case -EINPROGRESS:
1530                                 DBG_8723A("ERROR: URB IS IN PROGRESS!/n");
1531                                 break;
1532                         default:
1533                                 break;
1534                 }
1535
1536         }
1537
1538 exit:
1539
1540 _func_exit_;
1541
1542 }
1543
1544 static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
1545 {
1546         _irqL irqL;
1547         int err;
1548         unsigned int pipe;
1549         SIZE_PTR tmpaddr=0;
1550         SIZE_PTR alignment=0;
1551         u32 ret = _SUCCESS;
1552         PURB purb = NULL;
1553         struct recv_buf *precvbuf = (struct recv_buf *)rmem;
1554         _adapter                *adapter = pintfhdl->padapter;
1555         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
1556         struct recv_priv        *precvpriv = &adapter->recvpriv;
1557         struct usb_device       *pusbd = pdvobj->pusbdev;
1558
1559
1560 _func_enter_;
1561
1562         if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)
1563         {
1564                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
1565                 return _FAIL;
1566         }
1567
1568 #ifdef CONFIG_PREALLOC_RECV_SKB
1569         if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL))
1570         {
1571                 if (NULL != (precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue)))
1572                 {
1573                         precvbuf->reuse = _TRUE;
1574                 }
1575         }
1576 #endif
1577
1578
1579         if(precvbuf !=NULL)
1580         {
1581                 rtl8192cu_init_recvbuf(adapter, precvbuf);
1582
1583                 //re-assign for linux based on skb
1584                 if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL))
1585                 {
1586                         //precvbuf->pskb = alloc_skb(MAX_RECVBUF_SZ, GFP_ATOMIC);//don't use this after v2.6.25
1587 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
1588                         precvbuf->pskb = dev_alloc_skb(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1589 #else
1590                         precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1591 #endif
1592                         if(precvbuf->pskb == NULL)
1593                         {
1594                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("init_recvbuf(): alloc_skb fail!\n"));
1595                                 return _FAIL;
1596                         }
1597
1598                         tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
1599                         alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
1600                         skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
1601
1602                         precvbuf->phead = precvbuf->pskb->head;
1603                         precvbuf->pdata = precvbuf->pskb->data;
1604                         precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1605                         precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1606                         precvbuf->pbuf = precvbuf->pskb->data;
1607                 }
1608                 else//reuse skb
1609                 {
1610                         precvbuf->phead = precvbuf->pskb->head;
1611                         precvbuf->pdata = precvbuf->pskb->data;
1612                         precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1613                         precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1614                 precvbuf->pbuf = precvbuf->pskb->data;
1615
1616                         precvbuf->reuse = _FALSE;
1617                 }
1618
1619                 //_enter_critical(&precvpriv->lock, &irqL);
1620                 //precvpriv->rx_pending_cnt++;
1621                 //precvbuf->irp_pending = _TRUE;
1622                 //_exit_critical(&precvpriv->lock, &irqL);
1623
1624                 precvpriv->rx_pending_cnt++;
1625
1626                 purb = precvbuf->purb;
1627
1628                 //translate DMA FIFO addr to pipehandle
1629                 pipe = ffaddr2pipehdl(pdvobj, addr);
1630
1631                 usb_fill_bulk_urb(purb, pusbd, pipe,
1632                                                 precvbuf->pbuf,
1633                                                 MAX_RECVBUF_SZ,
1634                                                 usb_read_port_complete,
1635                                                 precvbuf);//context is precvbuf
1636
1637                 err = usb_submit_urb(purb, GFP_ATOMIC);
1638                 if((err) && (err != (-EPERM)))
1639                 {
1640                         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status));
1641                         DBG_8723A("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status);
1642                         ret = _FAIL;
1643                 }
1644         }
1645         else
1646         {
1647                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n"));
1648                 ret = _FAIL;
1649         }
1650
1651 _func_exit_;
1652
1653         return ret;
1654 }
1655 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_RX
1656
1657 void rtl8192cu_xmit_tasklet(void *priv)
1658 {
1659         int ret = _FALSE;
1660         _adapter *padapter = (_adapter*)priv;
1661         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1662
1663         if(check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE)
1664                 return;
1665
1666         while(1)
1667         {
1668                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE) || (padapter->bWritePortCancel == _TRUE))
1669                 {
1670                         DBG_8723A("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
1671                         break;
1672                 }
1673
1674                 ret = rtl8192cu_xmitframe_complete(padapter, pxmitpriv, NULL);
1675
1676                 if(ret==_FALSE)
1677                         break;
1678
1679         }
1680
1681 }
1682
1683 void rtl8723au_set_intf_ops(struct _io_ops      *pops)
1684 {
1685         _func_enter_;
1686
1687         _rtw_memset((u8 *)pops, 0, sizeof(struct _io_ops));
1688
1689         pops->_read8 = &usb_read8;
1690         pops->_read16 = &usb_read16;
1691         pops->_read32 = &usb_read32;
1692         pops->_read_mem = &usb_read_mem;
1693         pops->_read_port = &usb_read_port;
1694
1695         pops->_write8 = &usb_write8;
1696         pops->_write16 = &usb_write16;
1697         pops->_write32 = &usb_write32;
1698         pops->_writeN = &usb_writeN;
1699
1700 #ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
1701         pops->_write8_async= &usb_async_write8;
1702         pops->_write16_async = &usb_async_write16;
1703         pops->_write32_async = &usb_async_write32;
1704 #endif
1705         pops->_write_mem = &usb_write_mem;
1706         pops->_write_port = &usb_write_port;
1707
1708         pops->_read_port_cancel = &usb_read_port_cancel;
1709         pops->_write_port_cancel = &usb_write_port_cancel;
1710
1711 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
1712         pops->_read_interrupt = &usb_read_interrupt;
1713 #endif
1714
1715         _func_exit_;
1716
1717 }
1718 void rtl8723au_set_hw_type(_adapter *padapter)
1719 {
1720         padapter->chip_type = RTL8723A;
1721         padapter->HardwareType = HARDWARE_TYPE_RTL8723AU;
1722         DBG_8723A("CHIP TYPE: RTL8723A\n");
1723 }