OSDN Git Service

Elminate multiple layers of wrappers for work handling
[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         PADAPTER                        Adapter,
494         void *                          pContent,
495         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                         schedule_work(&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                                 schedule_work(&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                                 schedule_work(&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                                 schedule_work(&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                 INIT_LIST_HEAD(&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                 pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
753                 if(pkt_copy)
754                 {
755                         pkt_copy->dev = padapter->pnetdev;
756                         precvframe->u.hdr.pkt = pkt_copy;
757                         precvframe->u.hdr.rx_head = pkt_copy->data;
758                         precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
759                         skb_reserve(pkt_copy, 8 - ((unsigned long)(pkt_copy->data) & 7));//force pkt_copy->data at 8-byte alignment address
760                         skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
761                         memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
762                         precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
763                 }
764                 else
765                 {
766                         DBG_8723A("recvbuf2recvframe:can not allocate memory for skb copy\n");
767                         //precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC);
768                         //precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pbuf;
769                         //precvframe->u.hdr.rx_end = pbuf + (pkt_offset>1612?pkt_offset:1612);
770
771                         precvframe->u.hdr.pkt = NULL;
772                         rtw_free_recvframe(precvframe, pfree_recv_queue);
773
774                         goto _exit_recvbuf2recvframe;
775                 }
776
777                 recvframe_put(precvframe, skb_len);
778                 //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
779
780                 if (pattrib->physt)
781                 {
782                         pphy_info = (struct phy_stat*)(pbuf + RXDESC_OFFSET);
783                         update_recvframe_phyinfo(precvframe, pphy_info);
784                 }
785
786 #ifdef CONFIG_USB_RX_AGGREGATION
787                 switch(pHalData->UsbRxAggMode)
788                 {
789                         case USB_RX_AGG_DMA:
790                         case USB_RX_AGG_MIX:
791                                 pkt_offset = (u16)_RND128(pkt_offset);
792                                 break;
793                                 case USB_RX_AGG_USB:
794                                 pkt_offset = (u16)_RND4(pkt_offset);
795                                 break;
796                         case USB_RX_AGG_DISABLE:
797                         default:
798                                 break;
799                 }
800 #endif
801
802                 if(rtw_recv_entry(precvframe) != _SUCCESS)
803                 {
804                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
805                 }
806
807                 pkt_cnt--;
808                 transfer_len -= pkt_offset;
809                 pbuf += pkt_offset;
810                 precvframe = NULL;
811                 pkt_copy = NULL;
812
813                 if(transfer_len>0 && pkt_cnt==0)
814                         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
815
816         }while((transfer_len>0) && (pkt_cnt>0));
817
818 _exit_recvbuf2recvframe:
819
820         return _SUCCESS;
821 }
822
823 void rtl8192cu_recv_tasklet(void *priv)
824 {
825         struct recv_buf *precvbuf = NULL;
826         _adapter        *padapter = (_adapter*)priv;
827         struct recv_priv        *precvpriv = &padapter->recvpriv;
828
829         while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue)))
830         {
831                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
832                 {
833                         DBG_8723A("recv_tasklet => bDriverStopped or bSurpriseRemoved \n");
834
835                         break;
836                 }
837
838
839                 recvbuf2recvframe(padapter, precvbuf);
840
841                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
842         }
843
844 }
845
846 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
847 {
848         struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
849         _adapter                        *padapter =(_adapter *)precvbuf->adapter;
850         struct recv_priv        *precvpriv = &padapter->recvpriv;
851
852         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n"));
853
854         precvpriv->rx_pending_cnt --;
855
856         if(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel)
857         {
858                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved));
859
860                 goto exit;
861         }
862
863         if(purb->status==0)//SUCCESS
864         {
865                 if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE))
866                 {
867                         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"));
868
869                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
870                 }
871                 else
872                 {
873                         rtw_reset_continual_urb_error(adapter_to_dvobj(padapter));
874
875                         precvbuf->transfer_len = purb->actual_length;
876
877                         //rtw_enqueue_rx_transfer_buffer(precvpriv, rx_transfer_buf);
878                         rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue);
879
880                         tasklet_schedule(&precvpriv->recv_tasklet);
881                 }
882         }
883         else
884         {
885                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status));
886
887                 DBG_8723A("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
888
889                 if(rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(padapter)) == _TRUE ){
890                         padapter->bSurpriseRemoved = _TRUE;
891                 }
892
893                 switch(purb->status) {
894                         case -EINVAL:
895                         case -EPIPE:
896                         case -ENODEV:
897                         case -ESHUTDOWN:
898                                 //padapter->bSurpriseRemoved=_TRUE;
899                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n"));
900                         case -ENOENT:
901                                 padapter->bDriverStopped=_TRUE;
902                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n"));
903                                 break;
904                         case -EPROTO:
905                         case -EOVERFLOW:
906                                 #ifdef DBG_CONFIG_ERROR_DETECT
907                                 {
908                                         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
909                                         pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
910                                 }
911                                 #endif
912                                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
913                                 break;
914                         case -EINPROGRESS:
915                                 DBG_8723A("ERROR: URB IS IN PROGRESS!/n");
916                                 break;
917                         default:
918                                 break;
919                 }
920
921         }
922
923 exit:
924
925 _func_exit_;
926
927 }
928
929 static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
930 {
931         int err;
932         unsigned int pipe;
933         u32 ret = _SUCCESS;
934         struct urb *purb = NULL;
935         struct recv_buf *precvbuf = (struct recv_buf *)rmem;
936         _adapter                *adapter = pintfhdl->padapter;
937         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
938         struct recv_priv        *precvpriv = &adapter->recvpriv;
939         struct usb_device       *pusbd = pdvobj->pusbdev;
940
941 _func_enter_;
942
943         if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)
944         {
945                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
946                 return _FAIL;
947         }
948
949         if(precvbuf !=NULL)
950         {
951                 rtl8192cu_init_recvbuf(adapter, precvbuf);
952
953                 if(precvbuf->pbuf)
954                 {
955                         precvpriv->rx_pending_cnt++;
956
957                         purb = precvbuf->purb;
958
959                         //translate DMA FIFO addr to pipehandle
960                         pipe = ffaddr2pipehdl(pdvobj, addr);
961
962                         usb_fill_bulk_urb(purb, pusbd, pipe,
963                                                 precvbuf->pbuf,
964                                                 MAX_RECVBUF_SZ,
965                                                 usb_read_port_complete,
966                                                 precvbuf);//context is precvbuf
967
968                         purb->transfer_dma = precvbuf->dma_transfer_addr;
969                         purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
970
971                         err = usb_submit_urb(purb, GFP_ATOMIC);
972                         if((err) && (err != (-EPERM)))
973                         {
974                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status));
975                                 DBG_8723A("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status);
976                                 ret = _FAIL;
977                         }
978
979                 }
980
981         }
982         else
983         {
984                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n"));
985                 ret = _FAIL;
986         }
987
988 _func_exit_;
989
990         return ret;
991 }
992 #else   // CONFIG_USE_USB_BUFFER_ALLOC_RX
993 static s32 pre_recv_entry(union recv_frame *precvframe, struct recv_stat *prxstat, struct phy_stat *pphy_info)
994 {
995         s32 ret=_SUCCESS;
996 #ifdef CONFIG_CONCURRENT_MODE
997         u8 *primary_myid, *secondary_myid, *paddr1;
998         union recv_frame        *precvframe_if2 = NULL;
999         _adapter *primary_padapter = precvframe->u.hdr.adapter;
1000         _adapter *secondary_padapter = primary_padapter->pbuddy_adapter;
1001         struct recv_priv *precvpriv = &primary_padapter->recvpriv;
1002         _queue *pfree_recv_queue = &precvpriv->free_recv_queue;
1003         u8      *pbuf = precvframe->u.hdr.rx_data;
1004
1005         if(!secondary_padapter)
1006                 return ret;
1007
1008         paddr1 = GetAddr1Ptr(precvframe->u.hdr.rx_data);
1009
1010         if(IS_MCAST(paddr1) == _FALSE)//unicast packets
1011         {
1012                 //primary_myid = myid(&primary_padapter->eeprompriv);
1013                 secondary_myid = myid(&secondary_padapter->eeprompriv);
1014
1015                 if (!memcmp(paddr1, secondary_myid, ETH_ALEN))
1016                 {
1017                         //change to secondary interface
1018                         precvframe->u.hdr.adapter = secondary_padapter;
1019                 }
1020
1021                 //ret = recv_entry(precvframe);
1022
1023         }
1024         else // Handle BC/MC Packets
1025         {
1026
1027                 u8 clone = _TRUE;
1028 #if 0
1029                 u8 type, subtype, *paddr2, *paddr3;
1030
1031                 type =  GetFrameType(pbuf);
1032                 subtype = GetFrameSubType(pbuf); //bit(7)~bit(2)
1033
1034                 switch (type)
1035                 {
1036                         case WIFI_MGT_TYPE: //Handle BC/MC mgnt Packets
1037                                 if(subtype == WIFI_BEACON)
1038                                 {
1039                                         paddr3 = GetAddr3Ptr(precvframe->u.hdr.rx_data);
1040
1041                                         if (check_fwstate(&secondary_padapter->mlmepriv, _FW_LINKED) &&
1042                                             !memcmp(paddr3, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN))
1043                                         {
1044                                                 //change to secondary interface
1045                                                 precvframe->u.hdr.adapter = secondary_padapter;
1046                                                 clone = _FALSE;
1047                                         }
1048
1049                                         if (check_fwstate(&primary_padapter->mlmepriv, _FW_LINKED) &&
1050                                             !memcmp(paddr3, get_bssid(&primary_padapter->mlmepriv), ETH_ALEN))
1051                                         {
1052                                                 if(clone==_FALSE)
1053                                                 {
1054                                                         clone = _TRUE;
1055                                                 }
1056                                                 else
1057                                                 {
1058                                                         clone = _FALSE;
1059                                                 }
1060
1061                                                 precvframe->u.hdr.adapter = primary_padapter;
1062                                         }
1063
1064                                         if(check_fwstate(&primary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) ||
1065                                                 check_fwstate(&secondary_padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING))
1066                                         {
1067                                                 clone = _TRUE;
1068                                                 precvframe->u.hdr.adapter = primary_padapter;
1069                                         }
1070
1071                                 }
1072                                 else if(subtype == WIFI_PROBEREQ)
1073                                 {
1074                                         //probe req frame is only for interface2
1075                                         //change to secondary interface
1076                                         precvframe->u.hdr.adapter = secondary_padapter;
1077                                         clone = _FALSE;
1078                                 }
1079                                 break;
1080                         case WIFI_CTRL_TYPE: // Handle BC/MC ctrl Packets
1081
1082                                 break;
1083                         case WIFI_DATA_TYPE: //Handle BC/MC data Packets
1084                                         //Notes: AP MODE never rx BC/MC data packets
1085
1086                                 paddr2 = GetAddr2Ptr(precvframe->u.hdr.rx_data);
1087
1088                                 if (!memcmp(paddr2, get_bssid(&secondary_padapter->mlmepriv), ETH_ALEN))
1089                                 {
1090                                         //change to secondary interface
1091                                         precvframe->u.hdr.adapter = secondary_padapter;
1092                                         clone = _FALSE;
1093                                 }
1094
1095                                 break;
1096                         default:
1097
1098                                 break;
1099                 }
1100 #endif
1101
1102                 if(_TRUE == clone)
1103                 {
1104                         //clone/copy to if2
1105                         u8 shift_sz = 0;
1106                         u32 alloc_sz, skb_len;
1107                         _pkt     *pkt_copy = NULL;
1108                         struct rx_pkt_attrib *pattrib = NULL;
1109
1110                         precvframe_if2 = rtw_alloc_recvframe(pfree_recv_queue);
1111                         if(precvframe_if2)
1112                         {
1113                                 precvframe_if2->u.hdr.adapter = secondary_padapter;
1114
1115                                 INIT_LIST_HEAD(&precvframe_if2->u.hdr.list);
1116                                 precvframe_if2->u.hdr.precvbuf = NULL;  //can't access the precvbuf for new arch.
1117                                 precvframe_if2->u.hdr.len=0;
1118
1119                                 memcpy(&precvframe_if2->u.hdr.attrib, &precvframe->u.hdr.attrib, sizeof(struct rx_pkt_attrib));
1120
1121                                 pattrib = &precvframe_if2->u.hdr.attrib;
1122
1123                                 //      Modified by Albert 20101213
1124                                 //      For 8 bytes IP header alignment.
1125                                 if (pattrib->qos)       //      Qos data, wireless lan header length is 26
1126                                 {
1127                                         shift_sz = 6;
1128                                 }
1129                                 else
1130                                 {
1131                                         shift_sz = 0;
1132                                 }
1133
1134                                 skb_len = pattrib->pkt_len;
1135
1136                                 // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
1137                                 // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
1138                                 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
1139                                         //alloc_sz = 1664;      //1664 is 128 alignment.
1140                                         if(skb_len <= 1650)
1141                                                 alloc_sz = 1664;
1142                                         else
1143                                                 alloc_sz = skb_len + 14;
1144                                 }
1145                                 else {
1146                                         alloc_sz = skb_len;
1147                                         //      6 is for IP header 8 bytes alignment in QoS packet case.
1148                                         //      8 is for skb->data 4 bytes alignment.
1149                                         alloc_sz += 14;
1150                                 }
1151
1152                                 pkt_copy = netdev_alloc_skb(secondary_padapter->pnetdev, alloc_sz);
1153                                 if(pkt_copy)
1154                                 {
1155                                         pkt_copy->dev = secondary_padapter->pnetdev;
1156                                         precvframe_if2->u.hdr.pkt = pkt_copy;
1157                                         precvframe_if2->u.hdr.rx_head = pkt_copy->data;
1158                                         precvframe_if2->u.hdr.rx_end = pkt_copy->data + alloc_sz;
1159                                         skb_reserve( pkt_copy, 8 - ((unsigned long)(pkt_copy->data) & 7));//force pkt_copy->data at 8-byte alignment address
1160                                         skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
1161                                         memcpy(pkt_copy->data, pbuf, skb_len);
1162                                         precvframe_if2->u.hdr.rx_data = precvframe_if2->u.hdr.rx_tail = pkt_copy->data;
1163
1164
1165                                         recvframe_put(precvframe_if2, skb_len);
1166                                         //recvframe_pull(precvframe_if2, drvinfo_sz + RXDESC_SIZE);
1167                                         if(pphy_info)
1168                                         update_recvframe_phyinfo(precvframe_if2, pphy_info);
1169                                         //rtl8192c_translate_rx_signal_stuff(precvframe_if2, pphy_info);
1170
1171                                         ret = rtw_recv_entry(precvframe_if2);
1172
1173                                 } else {
1174                                         rtw_free_recvframe(precvframe_if2, pfree_recv_queue);
1175                                         DBG_8723A("%s()-%d: alloc_skb() failed!\n", __FUNCTION__, __LINE__);
1176                                 }
1177
1178                         }
1179
1180                 }
1181
1182         }
1183
1184         ret = rtw_recv_entry(precvframe);
1185
1186 #endif
1187
1188         return ret;
1189
1190 }
1191
1192 static int recvbuf2recvframe(_adapter *padapter, _pkt *pskb)
1193 {
1194         u8      *pbuf;
1195         u8      shift_sz = 0;
1196         u16     pkt_cnt;
1197         u32     pkt_offset, skb_len, alloc_sz;
1198         s32     transfer_len;
1199         struct recv_stat        *prxstat;
1200         struct phy_stat *pphy_info = NULL;
1201         _pkt                            *pkt_copy = NULL;
1202         union recv_frame        *precvframe = NULL;
1203         struct rx_pkt_attrib    *pattrib = NULL;
1204         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
1205         struct recv_priv        *precvpriv = &padapter->recvpriv;
1206         _queue                  *pfree_recv_queue = &precvpriv->free_recv_queue;
1207
1208
1209         transfer_len = (s32)pskb->len;
1210         pbuf = pskb->data;
1211
1212         prxstat = (struct recv_stat *)pbuf;
1213         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
1214
1215 #if 0 //temp remove when disable usb rx aggregation
1216         if((pkt_cnt > 10) || (pkt_cnt < 1) || (transfer_len<RXDESC_SIZE) ||(pkt_len<=0))
1217         {
1218                 return _FAIL;
1219         }
1220 #endif
1221
1222         do{
1223                 RT_TRACE(_module_rtl871x_recv_c_, _drv_info_,
1224                          ("recvbuf2recvframe: rxdesc=offsset 0:0x%08x, 4:0x%08x, 8:0x%08x, C:0x%08x\n",
1225                           prxstat->rxdw0, prxstat->rxdw1, prxstat->rxdw2, prxstat->rxdw4));
1226
1227                 prxstat = (struct recv_stat *)pbuf;
1228
1229                 precvframe = rtw_alloc_recvframe(pfree_recv_queue);
1230                 if(precvframe==NULL)
1231                 {
1232                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: precvframe==NULL\n"));
1233                         DBG_8723A("%s()-%d: rtw_alloc_recvframe() failed! RX Drop!\n", __FUNCTION__, __LINE__);
1234                         goto _exit_recvbuf2recvframe;
1235                 }
1236
1237                 INIT_LIST_HEAD(&precvframe->u.hdr.list);
1238                 precvframe->u.hdr.precvbuf = NULL;      //can't access the precvbuf for new arch.
1239                 precvframe->u.hdr.len=0;
1240
1241 //              rtl8192c_query_rx_desc_status(precvframe, prxstat);
1242                 update_recvframe_attrib(precvframe, prxstat);
1243
1244                 pattrib = &precvframe->u.hdr.attrib;
1245
1246                 if(pattrib->crc_err){
1247                         DBG_8723A("%s()-%d: RX Warning! rx CRC ERROR !!\n", __FUNCTION__, __LINE__);
1248                         rtw_free_recvframe(precvframe, pfree_recv_queue);
1249                         goto _exit_recvbuf2recvframe;
1250                 }
1251
1252                 pkt_offset = RXDESC_SIZE + pattrib->drvinfo_sz + pattrib->shift_sz + pattrib->pkt_len;
1253
1254                 if((pattrib->pkt_len<=0) || (pkt_offset>transfer_len))
1255                 {
1256                         RT_TRACE(_module_rtl871x_recv_c_,_drv_info_,("recvbuf2recvframe: pkt_len<=0\n"));
1257                         DBG_8723A("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__);
1258                         rtw_free_recvframe(precvframe, pfree_recv_queue);
1259                         goto _exit_recvbuf2recvframe;
1260                 }
1261
1262                 //      Modified by Albert 20101213
1263                 //      For 8 bytes IP header alignment.
1264                 if (pattrib->qos)       //      Qos data, wireless lan header length is 26
1265                 {
1266                         shift_sz = 6;
1267                 }
1268                 else
1269                 {
1270                         shift_sz = 0;
1271                 }
1272
1273                 skb_len = pattrib->pkt_len;
1274
1275                 // for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet.
1276                 // modify alloc_sz for recvive crc error packet by thomas 2011-06-02
1277                 if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0)){
1278                         //alloc_sz = 1664;      //1664 is 128 alignment.
1279                         if(skb_len <= 1650)
1280                                 alloc_sz = 1664;
1281                         else
1282                                 alloc_sz = skb_len + 14;
1283                 }
1284                 else {
1285                         alloc_sz = skb_len;
1286                         //      6 is for IP header 8 bytes alignment in QoS packet case.
1287                         //      8 is for skb->data 4 bytes alignment.
1288                         alloc_sz += 14;
1289                 }
1290
1291                 pkt_copy = netdev_alloc_skb(padapter->pnetdev, alloc_sz);
1292                 if (pkt_copy)
1293                 {
1294                         pkt_copy->dev = padapter->pnetdev;
1295                         precvframe->u.hdr.pkt = pkt_copy;
1296                         precvframe->u.hdr.rx_head = pkt_copy->data;
1297                         precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
1298                         skb_reserve( pkt_copy, 8 - ((unsigned long)( pkt_copy->data ) & 7 ));//force pkt_copy->data at 8-byte alignment address
1299                         skb_reserve( pkt_copy, shift_sz );//force ip_hdr at 8-byte alignment address according to shift_sz.
1300                         memcpy(pkt_copy->data, (pbuf + pattrib->shift_sz + pattrib->drvinfo_sz + RXDESC_SIZE), skb_len);
1301                         precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
1302                 }
1303                 else
1304                 {
1305                         if((pattrib->mfrag == 1)&&(pattrib->frag_num == 0))
1306                         {
1307                                 DBG_8723A("recvbuf2recvframe: alloc_skb fail , drop frag frame \n");
1308                                 rtw_free_recvframe(precvframe, pfree_recv_queue);
1309                                 goto _exit_recvbuf2recvframe;
1310                         }
1311
1312                         precvframe->u.hdr.pkt = skb_clone(pskb, GFP_ATOMIC);
1313                         if(precvframe->u.hdr.pkt)
1314                         {
1315                                 precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail
1316                                         = pbuf+ pattrib->drvinfo_sz + RXDESC_SIZE;
1317                                 precvframe->u.hdr.rx_end =  pbuf +pattrib->drvinfo_sz + RXDESC_SIZE+ alloc_sz;
1318                         }
1319                         else
1320                         {
1321                                 DBG_8723A("recvbuf2recvframe: skb_clone fail\n");
1322                                 rtw_free_recvframe(precvframe, pfree_recv_queue);
1323                                 goto _exit_recvbuf2recvframe;
1324                         }
1325
1326                 }
1327
1328                 recvframe_put(precvframe, skb_len);
1329                 //recvframe_pull(precvframe, drvinfo_sz + RXDESC_SIZE);
1330
1331                 if (pattrib->physt)
1332                 {
1333                         pphy_info = (struct phy_stat*)(pbuf + RXDESC_OFFSET);
1334                         update_recvframe_phyinfo(precvframe, pphy_info);
1335                 }
1336
1337 #ifdef CONFIG_USB_RX_AGGREGATION
1338                 switch(pHalData->UsbRxAggMode)
1339                 {
1340                         case USB_RX_AGG_DMA:
1341                         case USB_RX_AGG_MIX:
1342                                 pkt_offset = (u16)_RND128(pkt_offset);
1343                                 break;
1344                                 case USB_RX_AGG_USB:
1345                                 pkt_offset = (u16)_RND4(pkt_offset);
1346                                 break;
1347                         case USB_RX_AGG_DISABLE:
1348                         default:
1349                                 break;
1350                 }
1351 #endif
1352
1353 #ifdef CONFIG_CONCURRENT_MODE
1354                 if(pre_recv_entry(precvframe, prxstat, pphy_info) != _SUCCESS)
1355                 {
1356                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: recv_entry(precvframe) != _SUCCESS\n"));
1357                 }
1358 #else
1359                 if(rtw_recv_entry(precvframe) != _SUCCESS)
1360                 {
1361                         RT_TRACE(_module_rtl871x_recv_c_,_drv_err_,("recvbuf2recvframe: rtw_recv_entry(precvframe) != _SUCCESS\n"));
1362                 }
1363 #endif
1364
1365                 pkt_cnt--;
1366                 transfer_len -= pkt_offset;
1367                 pbuf += pkt_offset;
1368                 precvframe = NULL;
1369                 pkt_copy = NULL;
1370
1371                 if(transfer_len>0 && pkt_cnt==0)
1372                         pkt_cnt = (le32_to_cpu(prxstat->rxdw2)>>16) & 0xff;
1373
1374         }while((transfer_len>0) && (pkt_cnt>0));
1375
1376 _exit_recvbuf2recvframe:
1377
1378         return _SUCCESS;
1379 }
1380
1381 void rtl8192cu_recv_tasklet(void *priv)
1382 {
1383         _pkt                    *pskb;
1384         _adapter                *padapter = (_adapter*)priv;
1385         struct recv_priv        *precvpriv = &padapter->recvpriv;
1386
1387         while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue)))
1388         {
1389                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE))
1390                 {
1391                         DBG_8723A("recv_tasklet => bDriverStopped or bSurpriseRemoved \n");
1392                         dev_kfree_skb_any(pskb);
1393                         break;
1394                 }
1395
1396                 recvbuf2recvframe(padapter, pskb);
1397
1398 #ifdef CONFIG_PREALLOC_RECV_SKB
1399
1400                 skb_reset_tail_pointer(pskb);
1401
1402                 pskb->len = 0;
1403
1404                 skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
1405
1406 #else
1407                 dev_kfree_skb_any(pskb);
1408 #endif
1409
1410         }
1411
1412 }
1413
1414
1415 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
1416 {
1417         uint isevt, *pbuf;
1418         struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
1419         _adapter                        *padapter =(_adapter *)precvbuf->adapter;
1420         struct recv_priv        *precvpriv = &padapter->recvpriv;
1421
1422         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n"));
1423
1424         precvpriv->rx_pending_cnt --;
1425
1426         //if(precvpriv->rx_pending_cnt== 0)
1427         //{
1428         //      RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: rx_pending_cnt== 0, set allrxreturnevt!\n"));
1429         //      up(&precvpriv->allrxreturnevt);
1430         //}
1431
1432         if(padapter->bSurpriseRemoved || padapter->bDriverStopped||padapter->bReadPortCancel)
1433         {
1434                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved));
1435
1436         #ifdef CONFIG_PREALLOC_RECV_SKB
1437                 precvbuf->reuse = _TRUE;
1438         #else
1439                 if(precvbuf->pskb){
1440                         DBG_8723A("==> free skb(%p)\n",precvbuf->pskb);
1441                         dev_kfree_skb_any(precvbuf->pskb);
1442                 }
1443         #endif
1444                 DBG_8723A("%s()-%d: RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) bReadPortCancel(%d)\n",
1445                 __FUNCTION__, __LINE__,padapter->bDriverStopped, padapter->bSurpriseRemoved,padapter->bReadPortCancel);
1446                 goto exit;
1447         }
1448
1449         if(purb->status==0)//SUCCESS
1450         {
1451                 if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE))
1452                 {
1453                         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"));
1454                         precvbuf->reuse = _TRUE;
1455                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
1456                         DBG_8723A("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__);
1457                 }
1458                 else
1459                 {
1460                         rtw_reset_continual_urb_error(adapter_to_dvobj(padapter));
1461
1462                         precvbuf->transfer_len = purb->actual_length;
1463                         skb_put(precvbuf->pskb, purb->actual_length);
1464                         skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
1465
1466                         if (skb_queue_len(&precvpriv->rx_skb_queue)<=1)
1467                                 tasklet_schedule(&precvpriv->recv_tasklet);
1468
1469                         precvbuf->pskb = NULL;
1470                         precvbuf->reuse = _FALSE;
1471                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
1472                 }
1473         }
1474         else
1475         {
1476                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status));
1477                 skb_put(precvbuf->pskb, purb->actual_length);
1478                 precvbuf->pskb = NULL;
1479
1480                 DBG_8723A("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
1481
1482                 if(rtw_inc_and_chk_continual_urb_error(adapter_to_dvobj(padapter)) == _TRUE ){
1483                         padapter->bSurpriseRemoved = _TRUE;
1484                 }
1485
1486                 switch(purb->status) {
1487                         case -EINVAL:
1488                         case -EPIPE:
1489                         case -ENODEV:
1490                         case -ESHUTDOWN:
1491                                 //padapter->bSurpriseRemoved=_TRUE;
1492                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n"));
1493                         case -ENOENT:
1494                                 padapter->bDriverStopped=_TRUE;
1495                                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n"));
1496                                 break;
1497                         case -EPROTO:
1498                         case -EOVERFLOW:
1499                                 #ifdef DBG_CONFIG_ERROR_DETECT
1500                                 {
1501                                         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
1502                                         pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
1503                                 }
1504                                 #endif
1505                                 precvbuf->reuse = _TRUE;
1506                                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
1507                                 break;
1508                         case -EINPROGRESS:
1509                                 DBG_8723A("ERROR: URB IS IN PROGRESS!/n");
1510                                 break;
1511                         default:
1512                                 break;
1513                 }
1514
1515         }
1516
1517 exit:
1518
1519 _func_exit_;
1520
1521 }
1522
1523 static u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
1524 {
1525         int err;
1526         unsigned int pipe;
1527         unsigned long tmpaddr = 0;
1528         unsigned long alignment = 0;
1529         u32 ret = _SUCCESS;
1530         struct urb *purb = NULL;
1531         struct recv_buf *precvbuf = (struct recv_buf *)rmem;
1532         _adapter                *adapter = pintfhdl->padapter;
1533         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
1534         struct recv_priv        *precvpriv = &adapter->recvpriv;
1535         struct usb_device       *pusbd = pdvobj->pusbdev;
1536
1537
1538 _func_enter_;
1539
1540         if(adapter->bDriverStopped || adapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx) {
1541                 RT_TRACE(_module_hci_ops_os_c_, _drv_err_,
1542                          ("usb_read_port:( padapter->bDriverStopped ||padapter->bSurpriseRemoved ||adapter->pwrctrlpriv.pnp_bstop_trx)!!!\n"));
1543                 return _FAIL;
1544         }
1545
1546         if (!precvbuf) {
1547                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port:precvbuf ==NULL\n"));
1548                 return _FAIL;
1549         }
1550
1551 #ifdef CONFIG_PREALLOC_RECV_SKB
1552         if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) {
1553                 if (NULL != (precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue)))
1554                         precvbuf->reuse = _TRUE;
1555         }
1556 #endif
1557
1558
1559         rtl8192cu_init_recvbuf(adapter, precvbuf);
1560
1561         //re-assign for linux based on skb
1562         if((precvbuf->reuse == _FALSE) || (precvbuf->pskb == NULL)) {
1563                 //precvbuf->pskb = alloc_skb(MAX_RECVBUF_SZ, GFP_ATOMIC);//don't use this after v2.6.25
1564                 precvbuf->pskb = netdev_alloc_skb(adapter->pnetdev, MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
1565                 if (precvbuf->pskb == NULL) {
1566                         RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("init_recvbuf(): alloc_skb fail!\n"));
1567                         return _FAIL;
1568                 }
1569
1570                 tmpaddr = (unsigned long)precvbuf->pskb->data;
1571                 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ-1);
1572                 skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
1573
1574                 precvbuf->phead = precvbuf->pskb->head;
1575                 precvbuf->pdata = precvbuf->pskb->data;
1576                 precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1577                 precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1578                 precvbuf->pbuf = precvbuf->pskb->data;
1579         } else { //reuse skb
1580                 precvbuf->phead = precvbuf->pskb->head;
1581                 precvbuf->pdata = precvbuf->pskb->data;
1582                 precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
1583                 precvbuf->pend = skb_end_pointer(precvbuf->pskb);
1584         precvbuf->pbuf = precvbuf->pskb->data;
1585
1586                 precvbuf->reuse = _FALSE;
1587         }
1588
1589         precvpriv->rx_pending_cnt++;
1590
1591         purb = precvbuf->purb;
1592
1593         //translate DMA FIFO addr to pipehandle
1594         pipe = ffaddr2pipehdl(pdvobj, addr);
1595
1596         usb_fill_bulk_urb(purb, pusbd, pipe,
1597                                         precvbuf->pbuf,
1598                                         MAX_RECVBUF_SZ,
1599                                         usb_read_port_complete,
1600                                         precvbuf);//context is precvbuf
1601
1602         err = usb_submit_urb(purb, GFP_ATOMIC);
1603         if((err) && (err != (-EPERM))) {
1604                 RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("cannot submit rx in-token(err=0x%.8x), URB_STATUS =0x%.8x", err, purb->status));
1605                 DBG_8723A("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n",err,purb->status);
1606                 ret = _FAIL;
1607         }
1608
1609 _func_exit_;
1610         return ret;
1611 }
1612 #endif  // CONFIG_USE_USB_BUFFER_ALLOC_RX
1613
1614 void rtl8192cu_xmit_tasklet(void *priv)
1615 {
1616         int ret = _FALSE;
1617         _adapter *padapter = (_adapter*)priv;
1618         struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
1619
1620         if(check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY) == _TRUE)
1621                 return;
1622
1623         while(1)
1624         {
1625                 if ((padapter->bDriverStopped == _TRUE)||(padapter->bSurpriseRemoved== _TRUE) || (padapter->bWritePortCancel == _TRUE))
1626                 {
1627                         DBG_8723A("xmit_tasklet => bDriverStopped or bSurpriseRemoved or bWritePortCancel\n");
1628                         break;
1629                 }
1630
1631                 ret = rtl8192cu_xmitframe_complete(padapter, pxmitpriv, NULL);
1632
1633                 if(ret==_FALSE)
1634                         break;
1635
1636         }
1637
1638 }
1639
1640 void rtl8723au_set_intf_ops(struct _io_ops      *pops)
1641 {
1642         _func_enter_;
1643
1644         memset((u8 *)pops, 0, sizeof(struct _io_ops));
1645
1646         pops->_read8 = &usb_read8;
1647         pops->_read16 = &usb_read16;
1648         pops->_read32 = &usb_read32;
1649         pops->_read_mem = &usb_read_mem;
1650         pops->_read_port = &usb_read_port;
1651
1652         pops->_write8 = &usb_write8;
1653         pops->_write16 = &usb_write16;
1654         pops->_write32 = &usb_write32;
1655         pops->_writeN = &usb_writeN;
1656
1657 #ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
1658         pops->_write8_async= &usb_async_write8;
1659         pops->_write16_async = &usb_async_write16;
1660         pops->_write32_async = &usb_async_write32;
1661 #endif
1662         pops->_write_mem = &usb_write_mem;
1663         pops->_write_port = &usb_write_port;
1664
1665         pops->_read_port_cancel = &usb_read_port_cancel;
1666         pops->_write_port_cancel = &usb_write_port_cancel;
1667
1668 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
1669         pops->_read_interrupt = &usb_read_interrupt;
1670 #endif
1671
1672         _func_exit_;
1673
1674 }
1675
1676 void rtl8723au_set_hw_type(_adapter *padapter)
1677 {
1678         padapter->chip_type = RTL8723A;
1679         padapter->HardwareType = HARDWARE_TYPE_RTL8723AU;
1680         DBG_8723A("CHIP TYPE: RTL8723A\n");
1681 }