OSDN Git Service

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