OSDN Git Service

56bc39fa033b1763f5eba4190139456ea269aa92
[android-x86/external-kernel-drivers.git] / rtl8812au / os_dep / linux / usb_ops_linux.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 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 #define _USB_OPS_LINUX_C_
20
21 #include <drv_types.h>
22 #include <hal_data.h>
23 #include <rtw_sreset.h>
24
25 struct rtw_async_write_data {
26         u8 data[VENDOR_CMD_MAX_DATA_LEN];
27         struct usb_ctrlrequest dr;
28 };
29
30 int usbctrl_vendorreq(struct intf_hdl *pintfhdl, u8 request, u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
31 {
32         _adapter        *padapter = pintfhdl->padapter;
33         struct dvobj_priv  *pdvobjpriv = adapter_to_dvobj(padapter);
34         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobjpriv);
35         struct usb_device *udev = pdvobjpriv->pusbdev;
36
37         unsigned int pipe;
38         int status = 0;
39         u32 tmp_buflen = 0;
40         u8 reqtype;
41         u8 *pIo_buf;
42         int vendorreq_times = 0;
43
44 #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
45         u8 *tmp_buf;
46 #else /* use stack memory */
47         u8 tmp_buf[MAX_USB_IO_CTL_SIZE];
48 #endif
49
50         /* RTW_INFO("%s %s:%d\n",__FUNCTION__, current->comm, current->pid); */
51
52         if (RTW_CANNOT_IO(padapter)) {
53                 status = -EPERM;
54                 goto exit;
55         }
56
57         if (len > MAX_VENDOR_REQ_CMD_SIZE) {
58                 RTW_INFO("[%s] Buffer len error ,vendor request failed\n", __FUNCTION__);
59                 status = -EINVAL;
60                 goto exit;
61         }
62
63 #ifdef CONFIG_USB_VENDOR_REQ_MUTEX
64         _enter_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL);
65 #endif
66
67
68         /* Acquire IO memory for vendorreq */
69 #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_PREALLOC
70         pIo_buf = pdvobjpriv->usb_vendor_req_buf;
71 #else
72         #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
73         tmp_buf = rtw_malloc((u32) len + ALIGNMENT_UNIT);
74         tmp_buflen = (u32)len + ALIGNMENT_UNIT;
75         #else /* use stack memory */
76         tmp_buflen = MAX_USB_IO_CTL_SIZE;
77         #endif
78
79         /* Added by Albert 2010/02/09 */
80         /* For mstar platform, mstar suggests the address for USB IO should be 16 bytes alignment. */
81         /* Trying to fix it here. */
82         pIo_buf = (tmp_buf == NULL) ? NULL : tmp_buf + ALIGNMENT_UNIT - ((SIZE_PTR)(tmp_buf) & 0x0f);
83 #endif
84
85         if (pIo_buf == NULL) {
86                 RTW_INFO("[%s] pIo_buf == NULL\n", __FUNCTION__);
87                 status = -ENOMEM;
88                 goto release_mutex;
89         }
90
91         while (++vendorreq_times <= MAX_USBCTRL_VENDORREQ_TIMES) {
92                 _rtw_memset(pIo_buf, 0, len);
93
94                 if (requesttype == 0x01) {
95                         pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
96                         reqtype =  REALTEK_USB_VENQT_READ;
97                 } else {
98                         pipe = usb_sndctrlpipe(udev, 0);/* write_out */
99                         reqtype =  REALTEK_USB_VENQT_WRITE;
100                         _rtw_memcpy(pIo_buf, pdata, len);
101                 }
102
103                 status = rtw_usb_control_msg(udev, pipe, request, reqtype, value, index, pIo_buf, len, RTW_USB_CONTROL_MSG_TIMEOUT);
104
105                 if (status == len) {  /* Success this control transfer. */
106                         rtw_reset_continual_io_error(pdvobjpriv);
107                         if (requesttype == 0x01) {
108                                 /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */
109                                 _rtw_memcpy(pdata, pIo_buf,  len);
110                         }
111                 } else { /* error cases */
112                         RTW_INFO("reg 0x%x, usb %s %u fail, status:%d value=0x%x, vendorreq_times:%d\n"
113                                 , value, (requesttype == 0x01) ? "read" : "write" , len, status, *(u32 *)pdata, vendorreq_times);
114
115                         if (status < 0) {
116                                 if (status == (-ESHUTDOWN)      || status == -ENODEV)
117                                         rtw_set_surprise_removed(padapter);
118                                 else {
119                                         #ifdef DBG_CONFIG_ERROR_DETECT
120                                         {
121                                                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
122                                                 pHalData->srestpriv.Wifi_Error_Status = USB_VEN_REQ_CMD_FAIL;
123                                         }
124                                         #endif
125                                 }
126                         } else { /* status != len && status >= 0 */
127                                 if (status > 0) {
128                                         if (requesttype == 0x01) {
129                                                 /* For Control read transfer, we have to copy the read data from pIo_buf to pdata. */
130                                                 _rtw_memcpy(pdata, pIo_buf,  len);
131                                         }
132                                 }
133                         }
134
135                         if (rtw_inc_and_chk_continual_io_error(pdvobjpriv) == _TRUE) {
136                                 rtw_set_surprise_removed(padapter);
137                                 break;
138                         }
139
140                 }
141
142                 /* firmware download is checksumed, don't retry */
143                 if ((value >= FW_START_ADDRESS) || status == len)
144                         break;
145
146         }
147
148         /* release IO memory used by vendorreq */
149 #ifdef CONFIG_USB_VENDOR_REQ_BUFFER_DYNAMIC_ALLOCATE
150         rtw_mfree(tmp_buf, tmp_buflen);
151 #endif
152
153 release_mutex:
154 #ifdef CONFIG_USB_VENDOR_REQ_MUTEX
155         _exit_critical_mutex(&pdvobjpriv->usb_vendor_req_mutex, NULL);
156 #endif
157 exit:
158         return status;
159
160 }
161
162 #ifdef CONFIG_USB_SUPPORT_ASYNC_VDN_REQ
163 static void _usbctrl_vendorreq_async_callback(struct urb *urb, struct pt_regs *regs)
164 {
165         if (urb) {
166                 if (urb->context)
167                         rtw_mfree(urb->context, sizeof(struct rtw_async_write_data));
168                 usb_free_urb(urb);
169         }
170 }
171
172 int _usbctrl_vendorreq_async_write(struct usb_device *udev, u8 request,
173         u16 value, u16 index, void *pdata, u16 len, u8 requesttype)
174 {
175         int rc;
176         unsigned int pipe;
177         u8 reqtype;
178         struct usb_ctrlrequest *dr;
179         struct urb *urb;
180         struct rtw_async_write_data *buf;
181
182
183         if (requesttype == VENDOR_READ) {
184                 pipe = usb_rcvctrlpipe(udev, 0);/* read_in */
185                 reqtype =  REALTEK_USB_VENQT_READ;
186         } else {
187                 pipe = usb_sndctrlpipe(udev, 0);/* write_out */
188                 reqtype =  REALTEK_USB_VENQT_WRITE;
189         }
190
191         buf = (struct rtl819x_async_write_data *)rtw_zmalloc(sizeof(*buf));
192         if (!buf) {
193                 rc = -ENOMEM;
194                 goto exit;
195         }
196
197         urb = usb_alloc_urb(0, GFP_ATOMIC);
198         if (!urb) {
199                 rtw_mfree((u8 *)buf, sizeof(*buf));
200                 rc = -ENOMEM;
201                 goto exit;
202         }
203
204         dr = &buf->dr;
205
206         dr->bRequestType = reqtype;
207         dr->bRequest = request;
208         dr->wValue = cpu_to_le16(value);
209         dr->wIndex = cpu_to_le16(index);
210         dr->wLength = cpu_to_le16(len);
211
212         _rtw_memcpy(buf, pdata, len);
213
214         usb_fill_control_urb(urb, udev, pipe, (unsigned char *)dr, buf, len,
215                 _usbctrl_vendorreq_async_callback, buf);
216
217         rc = usb_submit_urb(urb, GFP_ATOMIC);
218         if (rc < 0) {
219                 rtw_mfree((u8 *)buf, sizeof(*buf));
220                 usb_free_urb(urb);
221         }
222
223 exit:
224         return rc;
225 }
226
227
228 #endif /* CONFIG_USB_SUPPORT_ASYNC_VDN_REQ */
229
230 unsigned int ffaddr2pipehdl(struct dvobj_priv *pdvobj, u32 addr)
231 {
232         unsigned int pipe = 0, ep_num = 0;
233         struct usb_device *pusbd = pdvobj->pusbdev;
234
235         if (addr == RECV_BULK_IN_ADDR)
236                 pipe = usb_rcvbulkpipe(pusbd, pdvobj->RtInPipe[0]);
237
238         else if (addr == RECV_INT_IN_ADDR)
239                 pipe = usb_rcvintpipe(pusbd, pdvobj->RtInPipe[1]);
240
241         else if (addr < HW_QUEUE_ENTRY) {
242 #ifdef RTW_HALMAC
243                 /* halmac already translate queue id to bulk out id */
244                 ep_num = pdvobj->RtOutPipe[addr];
245 #else
246                 ep_num = pdvobj->Queue2Pipe[addr];
247 #endif
248                 pipe = usb_sndbulkpipe(pusbd, ep_num);
249         }
250
251         return pipe;
252 }
253
254 struct zero_bulkout_context {
255         void *pbuf;
256         void *purb;
257         void *pirp;
258         void *padapter;
259 };
260
261 static void usb_bulkout_zero_complete(struct urb *purb, struct pt_regs *regs)
262 {
263         struct zero_bulkout_context *pcontext = (struct zero_bulkout_context *)purb->context;
264
265         /* RTW_INFO("+usb_bulkout_zero_complete\n"); */
266
267         if (pcontext) {
268                 if (pcontext->pbuf)
269                         rtw_mfree(pcontext->pbuf, sizeof(int));
270
271                 if (pcontext->purb && (pcontext->purb == purb))
272                         usb_free_urb(pcontext->purb);
273
274
275                 rtw_mfree((u8 *)pcontext, sizeof(struct zero_bulkout_context));
276         }
277
278
279 }
280
281 static u32 usb_bulkout_zero(struct intf_hdl *pintfhdl, u32 addr)
282 {
283         int pipe, status, len;
284         u32 ret;
285         unsigned char *pbuf;
286         struct zero_bulkout_context *pcontext;
287         PURB    purb = NULL;
288         _adapter *padapter = (_adapter *)pintfhdl->padapter;
289         struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
290         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj);
291         struct usb_device *pusbd = pdvobj->pusbdev;
292
293         /* RTW_INFO("%s\n", __func__); */
294
295
296         if (RTW_CANNOT_TX(padapter))
297                 return _FAIL;
298
299
300         pcontext = (struct zero_bulkout_context *)rtw_zmalloc(sizeof(struct zero_bulkout_context));
301         if (pcontext == NULL)
302                 return _FAIL;
303
304         pbuf = (unsigned char *)rtw_zmalloc(sizeof(int));
305         purb = usb_alloc_urb(0, GFP_ATOMIC);
306
307         /* translate DMA FIFO addr to pipehandle */
308         pipe = ffaddr2pipehdl(pdvobj, addr);
309
310         len = 0;
311         pcontext->pbuf = pbuf;
312         pcontext->purb = purb;
313         pcontext->pirp = NULL;
314         pcontext->padapter = padapter;
315
316
317         /* translate DMA FIFO addr to pipehandle */
318         /* pipe = ffaddr2pipehdl(pdvobj, addr);  */
319
320         usb_fill_bulk_urb(purb, pusbd, pipe,
321                           pbuf,
322                           len,
323                           usb_bulkout_zero_complete,
324                           pcontext);/* context is pcontext */
325
326         status = usb_submit_urb(purb, GFP_ATOMIC);
327
328         if (!status)
329                 ret = _SUCCESS;
330         else
331                 ret = _FAIL;
332
333
334         return _SUCCESS;
335
336 }
337
338 void usb_read_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
339 {
340
341 }
342
343 void usb_write_mem(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
344 {
345
346 }
347
348
349 void usb_read_port_cancel(struct intf_hdl *pintfhdl)
350 {
351         int i;
352         struct recv_buf *precvbuf;
353         _adapter        *padapter = pintfhdl->padapter;
354         precvbuf = (struct recv_buf *)padapter->recvpriv.precv_buf;
355
356         RTW_INFO("%s\n", __func__);
357
358         for (i = 0; i < NR_RECVBUFF ; i++) {
359
360                 if (precvbuf->purb)      {
361                         /* RTW_INFO("usb_read_port_cancel : usb_kill_urb\n"); */
362                         usb_kill_urb(precvbuf->purb);
363                 }
364                 precvbuf++;
365         }
366
367 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
368         usb_kill_urb(padapter->recvpriv.int_in_urb);
369 #endif
370 }
371
372 static void usb_write_port_complete(struct urb *purb, struct pt_regs *regs)
373 {
374         _irqL irqL;
375         int i;
376         struct xmit_buf *pxmitbuf = (struct xmit_buf *)purb->context;
377         /* struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data; */
378         /* _adapter                     *padapter = pxmitframe->padapter; */
379         _adapter        *padapter = pxmitbuf->padapter;
380         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
381         /* struct pkt_attrib *pattrib = &pxmitframe->attrib; */
382
383
384         switch (pxmitbuf->flags) {
385         case VO_QUEUE_INX:
386                 pxmitpriv->voq_cnt--;
387                 break;
388         case VI_QUEUE_INX:
389                 pxmitpriv->viq_cnt--;
390                 break;
391         case BE_QUEUE_INX:
392                 pxmitpriv->beq_cnt--;
393                 break;
394         case BK_QUEUE_INX:
395                 pxmitpriv->bkq_cnt--;
396                 break;
397         default:
398                 break;
399         }
400
401
402         /*
403                 _enter_critical(&pxmitpriv->lock, &irqL);
404
405                 pxmitpriv->txirp_cnt--;
406
407                 switch(pattrib->priority)
408                 {
409                         case 1:
410                         case 2:
411                                 pxmitpriv->bkq_cnt--;
412
413                                 break;
414                         case 4:
415                         case 5:
416                                 pxmitpriv->viq_cnt--;
417
418                                 break;
419                         case 6:
420                         case 7:
421                                 pxmitpriv->voq_cnt--;
422
423                                 break;
424                         case 0:
425                         case 3:
426                         default:
427                                 pxmitpriv->beq_cnt--;
428
429                                 break;
430
431                 }
432
433                 _exit_critical(&pxmitpriv->lock, &irqL);
434
435
436                 if(pxmitpriv->txirp_cnt==0)
437                 {
438                         _rtw_up_sema(&(pxmitpriv->tx_retevt));
439                 }
440         */
441         /* rtw_free_xmitframe(pxmitpriv, pxmitframe); */
442
443         if (RTW_CANNOT_TX(padapter)) {
444                 RTW_INFO("%s(): TX Warning! bDriverStopped(%s) OR bSurpriseRemoved(%s) pxmitbuf->buf_tag(%x)\n"
445                          , __func__
446                          , rtw_is_drv_stopped(padapter) ? "True" : "False"
447                          , rtw_is_surprise_removed(padapter) ? "True" : "False"
448                          , pxmitbuf->buf_tag);
449
450                 goto check_completion;
451         }
452
453
454         if (purb->status == 0) {
455
456         } else {
457                 RTW_INFO("###=> urb_write_port_complete status(%d)\n", purb->status);
458                 if ((purb->status == -EPIPE) || (purb->status == -EPROTO)) {
459                         /* usb_clear_halt(pusbdev, purb->pipe);  */
460                         /* msleep(10); */
461                         sreset_set_wifi_error_status(padapter, USB_WRITE_PORT_FAIL);
462                 } else if (purb->status == -EINPROGRESS) {
463                         goto check_completion;
464
465                 } else if (purb->status == -ENOENT) {
466                         RTW_INFO("%s: -ENOENT\n", __func__);
467                         goto check_completion;
468
469                 } else if (purb->status == -ECONNRESET) {
470                         RTW_INFO("%s: -ECONNRESET\n", __func__);
471                         goto check_completion;
472
473                 } else if (purb->status == -ESHUTDOWN) {
474                         rtw_set_drv_stopped(padapter);
475
476                         goto check_completion;
477                 } else {
478                         rtw_set_surprise_removed(padapter);
479                         RTW_INFO("bSurpriseRemoved=TRUE\n");
480
481                         goto check_completion;
482                 }
483         }
484
485         #ifdef DBG_CONFIG_ERROR_DETECT
486         {
487                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
488                 pHalData->srestpriv.last_tx_complete_time = rtw_get_current_time();
489         }
490         #endif
491
492 check_completion:
493         _enter_critical(&pxmitpriv->lock_sctx, &irqL);
494         rtw_sctx_done_err(&pxmitbuf->sctx,
495                 purb->status ? RTW_SCTX_DONE_WRITE_PORT_ERR : RTW_SCTX_DONE_SUCCESS);
496         _exit_critical(&pxmitpriv->lock_sctx, &irqL);
497
498         rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
499
500         /* if(rtw_txframes_pending(padapter))    */
501         {
502                 tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
503         }
504
505
506 }
507
508 u32 usb_write_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *wmem)
509 {
510         _irqL irqL;
511         unsigned int pipe;
512         int status;
513         u32 ret = _FAIL, bwritezero = _FALSE;
514         PURB    purb = NULL;
515         _adapter *padapter = (_adapter *)pintfhdl->padapter;
516         struct dvobj_priv       *pdvobj = adapter_to_dvobj(padapter);
517         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj);
518         struct xmit_priv        *pxmitpriv = &padapter->xmitpriv;
519         struct xmit_buf *pxmitbuf = (struct xmit_buf *)wmem;
520         struct xmit_frame *pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
521         struct usb_device *pusbd = pdvobj->pusbdev;
522         struct pkt_attrib *pattrib = &pxmitframe->attrib;
523
524
525
526         if (RTW_CANNOT_TX(padapter)) {
527 #ifdef DBG_TX
528                 RTW_INFO(" DBG_TX %s:%d bDriverStopped%s, bSurpriseRemoved:%s\n", __func__, __LINE__
529                          , rtw_is_drv_stopped(padapter) ? "True" : "False"
530                         , rtw_is_surprise_removed(padapter) ? "True" : "False");
531 #endif
532                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_TX_DENY);
533                 goto exit;
534         }
535
536         _enter_critical(&pxmitpriv->lock, &irqL);
537
538         switch (addr) {
539         case VO_QUEUE_INX:
540                 pxmitpriv->voq_cnt++;
541                 pxmitbuf->flags = VO_QUEUE_INX;
542                 break;
543         case VI_QUEUE_INX:
544                 pxmitpriv->viq_cnt++;
545                 pxmitbuf->flags = VI_QUEUE_INX;
546                 break;
547         case BE_QUEUE_INX:
548                 pxmitpriv->beq_cnt++;
549                 pxmitbuf->flags = BE_QUEUE_INX;
550                 break;
551         case BK_QUEUE_INX:
552                 pxmitpriv->bkq_cnt++;
553                 pxmitbuf->flags = BK_QUEUE_INX;
554                 break;
555         case HIGH_QUEUE_INX:
556                 pxmitbuf->flags = HIGH_QUEUE_INX;
557                 break;
558         default:
559                 pxmitbuf->flags = MGT_QUEUE_INX;
560                 break;
561         }
562
563         _exit_critical(&pxmitpriv->lock, &irqL);
564
565         purb    = pxmitbuf->pxmit_urb[0];
566
567         /* translate DMA FIFO addr to pipehandle */
568 #ifdef RTW_HALMAC
569         pipe = ffaddr2pipehdl(pdvobj, pxmitbuf->bulkout_id);
570 #else
571         pipe = ffaddr2pipehdl(pdvobj, addr);
572 #endif
573
574 #ifdef CONFIG_REDUCE_USB_TX_INT
575         if ((pxmitpriv->free_xmitbuf_cnt % NR_XMITBUFF == 0)
576             || (pxmitbuf->buf_tag > XMITBUF_DATA))
577                 purb->transfer_flags  &= (~URB_NO_INTERRUPT);
578         else {
579                 purb->transfer_flags  |=  URB_NO_INTERRUPT;
580                 /* RTW_INFO("URB_NO_INTERRUPT "); */
581         }
582 #endif
583
584
585         usb_fill_bulk_urb(purb, pusbd, pipe,
586                           pxmitframe->buf_addr, /* = pxmitbuf->pbuf */
587                           cnt,
588                           usb_write_port_complete,
589                           pxmitbuf);/* context is pxmitbuf */
590
591 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_TX
592         purb->transfer_dma = pxmitbuf->dma_transfer_addr;
593         purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
594         purb->transfer_flags |= URB_ZERO_PACKET;
595 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_TX */
596
597 #ifdef USB_PACKET_OFFSET_SZ
598 #if (USB_PACKET_OFFSET_SZ == 0)
599         purb->transfer_flags |= URB_ZERO_PACKET;
600 #endif
601 #endif
602
603         status = usb_submit_urb(purb, GFP_ATOMIC);
604         if (!status) {
605                 #ifdef DBG_CONFIG_ERROR_DETECT
606                 {
607                         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
608                         pHalData->srestpriv.last_tx_time = rtw_get_current_time();
609                 }
610                 #endif
611         } else {
612                 rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_WRITE_PORT_ERR);
613                 RTW_INFO("usb_write_port, status=%d\n", status);
614
615                 switch (status) {
616                 case -ENODEV:
617                         rtw_set_drv_stopped(padapter);
618                         break;
619                 default:
620                         break;
621                 }
622                 goto exit;
623         }
624
625         ret = _SUCCESS;
626
627         /* Commented by Albert 2009/10/13
628          * We add the URB_ZERO_PACKET flag to urb so that the host will send the zero packet automatically. */
629         /*
630                 if(bwritezero == _TRUE)
631                 {
632                         usb_bulkout_zero(pintfhdl, addr);
633                 }
634         */
635
636
637 exit:
638         if (ret != _SUCCESS)
639                 rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
640         return ret;
641
642 }
643
644 void usb_write_port_cancel(struct intf_hdl *pintfhdl)
645 {
646         int i, j;
647         _adapter        *padapter = pintfhdl->padapter;
648         struct xmit_buf *pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmitbuf;
649
650         RTW_INFO("%s\n", __func__);
651
652         for (i = 0; i < NR_XMITBUFF; i++) {
653                 for (j = 0; j < 8; j++) {
654                         if (pxmitbuf->pxmit_urb[j])
655                                 usb_kill_urb(pxmitbuf->pxmit_urb[j]);
656                 }
657                 pxmitbuf++;
658         }
659
660         pxmitbuf = (struct xmit_buf *)padapter->xmitpriv.pxmit_extbuf;
661         for (i = 0; i < NR_XMIT_EXTBUFF ; i++) {
662                 for (j = 0; j < 8; j++) {
663                         if (pxmitbuf->pxmit_urb[j])
664                                 usb_kill_urb(pxmitbuf->pxmit_urb[j]);
665                 }
666                 pxmitbuf++;
667         }
668 }
669
670 static void usb_init_recvbuf(_adapter *padapter, struct recv_buf *precvbuf)
671 {
672
673         precvbuf->transfer_len = 0;
674
675         precvbuf->len = 0;
676
677         precvbuf->ref_cnt = 0;
678
679         if (precvbuf->pbuf) {
680                 precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pbuf;
681                 precvbuf->pend = precvbuf->pdata + MAX_RECVBUF_SZ;
682         }
683
684 }
685
686 int recvbuf2recvframe(PADAPTER padapter, void *ptr);
687
688 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
689 void usb_recv_tasklet(void *priv)
690 {
691         struct recv_buf *precvbuf = NULL;
692         _adapter        *padapter = (_adapter *)priv;
693         struct recv_priv        *precvpriv = &padapter->recvpriv;
694
695         while (NULL != (precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue))) {
696                 if (RTW_CANNOT_RUN(padapter)) {
697                         RTW_INFO("recv_tasklet => bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
698                                 , rtw_is_drv_stopped(padapter)? "True" : "False"
699                                 , rtw_is_surprise_removed(padapter)? "True" : "False");
700                         break;
701                 }
702
703                 recvbuf2recvframe(padapter, precvbuf);
704
705                 rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
706         }
707 }
708
709 void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
710 {
711         struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
712         _adapter                        *padapter = (_adapter *)precvbuf->adapter;
713         struct recv_priv        *precvpriv = &padapter->recvpriv;
714
715         ATOMIC_DEC(&(precvpriv->rx_pending_cnt));
716
717         if (RTW_CANNOT_RX(padapter)) {
718                 RTW_INFO("%s() RX Warning! bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
719                          , __func__
720                          , rtw_is_drv_stopped(padapter) ? "True" : "False"
721                         , rtw_is_surprise_removed(padapter) ? "True" : "False");
722                 return;
723         }
724
725         if (purb->status == 0) {
726
727                 if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
728                         RTW_INFO("%s()-%d: urb->actual_length:%u, MAX_RECVBUF_SZ:%u, RXDESC_SIZE:%u\n"
729                                 , __FUNCTION__, __LINE__, purb->actual_length, MAX_RECVBUF_SZ, RXDESC_SIZE);
730                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
731                 } else {
732                         rtw_reset_continual_io_error(adapter_to_dvobj(padapter));
733
734                         precvbuf->transfer_len = purb->actual_length;
735
736                         rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue);
737
738                         tasklet_schedule(&precvpriv->recv_tasklet);
739                 }
740         } else {
741
742                 RTW_INFO("###=> usb_read_port_complete => urb.status(%d)\n", purb->status);
743
744                 if (rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE)
745                         rtw_set_surprise_removed(padapter);
746
747                 switch (purb->status) {
748                 case -EINVAL:
749                 case -EPIPE:
750                 case -ENODEV:
751                 case -ESHUTDOWN:
752                 case -ENOENT:
753                         rtw_set_drv_stopped(padapter);
754                         break;
755                 case -EPROTO:
756                 case -EILSEQ:
757                 case -ETIME:
758                 case -ECOMM:
759                 case -EOVERFLOW:
760                         #ifdef DBG_CONFIG_ERROR_DETECT
761                         {
762                                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
763                                 pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
764                         }
765                         #endif
766                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
767                         break;
768                 case -EINPROGRESS:
769                         RTW_INFO("ERROR: URB IS IN PROGRESS!/n");
770                         break;
771                 default:
772                         break;
773                 }
774         }
775
776 }
777
778 u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
779 {
780         int err;
781         unsigned int pipe;
782         u32 ret = _SUCCESS;
783         PURB purb = NULL;
784         struct recv_buf *precvbuf = (struct recv_buf *)rmem;
785         _adapter                *adapter = pintfhdl->padapter;
786         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
787         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj);
788         struct recv_priv        *precvpriv = &adapter->recvpriv;
789         struct usb_device       *pusbd = pdvobj->pusbdev;
790
791
792         if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) {
793                 return _FAIL;
794         }
795
796         usb_init_recvbuf(adapter, precvbuf);
797
798         if (precvbuf->pbuf) {
799                 ATOMIC_INC(&(precvpriv->rx_pending_cnt));
800                 purb = precvbuf->purb;
801
802                 /* translate DMA FIFO addr to pipehandle */
803                 pipe = ffaddr2pipehdl(pdvobj, addr);
804
805                 usb_fill_bulk_urb(purb, pusbd, pipe,
806                         precvbuf->pbuf,
807                         MAX_RECVBUF_SZ,
808                         usb_read_port_complete,
809                         precvbuf);/* context is precvbuf */
810
811                 purb->transfer_dma = precvbuf->dma_transfer_addr;
812                 purb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
813
814                 err = usb_submit_urb(purb, GFP_ATOMIC);
815                 if ((err) && (err != (-EPERM))) {
816                         RTW_INFO("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n", err, purb->status);
817                         ret = _FAIL;
818                 }
819
820         }
821
822
823         return ret;
824 }
825 #else   /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
826
827 void usb_recv_tasklet(void *priv)
828 {
829         _pkt                    *pskb;
830         _adapter                *padapter = (_adapter *)priv;
831         struct recv_priv        *precvpriv = &padapter->recvpriv;
832         struct recv_buf *precvbuf = NULL;
833
834         while (NULL != (pskb = skb_dequeue(&precvpriv->rx_skb_queue))) {
835
836                 if (RTW_CANNOT_RUN(padapter)) {
837                         RTW_INFO("recv_tasklet => bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
838                                 , rtw_is_drv_stopped(padapter) ? "True" : "False"
839                                 , rtw_is_surprise_removed(padapter) ? "True" : "False");
840                         #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
841                         if (rtw_free_skb_premem(pskb) != 0)
842                         #endif /* CONFIG_PREALLOC_RX_SKB_BUFFER */
843                                 rtw_skb_free(pskb);
844                         break;
845                 }
846
847                 recvbuf2recvframe(padapter, pskb);
848
849                 skb_reset_tail_pointer(pskb);
850                 pskb->len = 0;
851
852                 skb_queue_tail(&precvpriv->free_recv_skb_queue, pskb);
853
854                 precvbuf = rtw_dequeue_recvbuf(&precvpriv->recv_buf_pending_queue);
855                 if (NULL != precvbuf) {
856                         precvbuf->pskb = NULL;
857                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
858                 }
859         }
860 }
861
862 static void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
863 {
864         struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
865         _adapter                        *padapter = (_adapter *)precvbuf->adapter;
866         struct recv_priv        *precvpriv = &padapter->recvpriv;
867
868         ATOMIC_DEC(&(precvpriv->rx_pending_cnt));
869
870         if (RTW_CANNOT_RX(padapter)) {
871                 RTW_INFO("%s() RX Warning! bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
872                         , __func__
873                         , rtw_is_drv_stopped(padapter) ? "True" : "False"
874                         , rtw_is_surprise_removed(padapter) ? "True" : "False");
875                 goto exit;
876         }
877
878         if (purb->status == 0) {
879
880                 if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)) {
881                         RTW_INFO("%s()-%d: urb->actual_length:%u, MAX_RECVBUF_SZ:%u, RXDESC_SIZE:%u\n"
882                                 , __FUNCTION__, __LINE__, purb->actual_length, MAX_RECVBUF_SZ, RXDESC_SIZE);
883                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
884                 } else {
885                         rtw_reset_continual_io_error(adapter_to_dvobj(padapter));
886
887                         precvbuf->transfer_len = purb->actual_length;
888                         skb_put(precvbuf->pskb, purb->actual_length);
889                         skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
890
891                         #ifndef CONFIG_FIX_NR_BULKIN_BUFFER
892                         if (skb_queue_len(&precvpriv->rx_skb_queue) <= 1)
893                         #endif
894                                 tasklet_schedule(&precvpriv->recv_tasklet);
895
896                         precvbuf->pskb = NULL;
897                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
898                 }
899         } else {
900
901                 RTW_INFO("###=> usb_read_port_complete => urb.status(%d)\n", purb->status);
902
903                 if (rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE)
904                         rtw_set_surprise_removed(padapter);
905
906                 switch (purb->status) {
907                 case -EINVAL:
908                 case -EPIPE:
909                 case -ENODEV:
910                 case -ESHUTDOWN:
911                 case -ENOENT:
912                         rtw_set_drv_stopped(padapter);
913                         break;
914                 case -EPROTO:
915                 case -EILSEQ:
916                 case -ETIME:
917                 case -ECOMM:
918                 case -EOVERFLOW:
919                         #ifdef DBG_CONFIG_ERROR_DETECT
920                         {
921                                 HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(padapter);
922                                 pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
923                         }
924                         #endif
925                         rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
926                         break;
927                 case -EINPROGRESS:
928                         RTW_INFO("ERROR: URB IS IN PROGRESS!/n");
929                         break;
930                 default:
931                         break;
932                 }
933         }
934
935 exit:
936         return;
937 }
938
939 u32 usb_read_port(struct intf_hdl *pintfhdl, u32 addr, u32 cnt, u8 *rmem)
940 {
941         int err;
942         unsigned int pipe;
943         u32 ret = _FAIL;
944         PURB purb = NULL;
945         struct recv_buf *precvbuf = (struct recv_buf *)rmem;
946         _adapter                *adapter = pintfhdl->padapter;
947         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
948         struct pwrctrl_priv *pwrctl = dvobj_to_pwrctl(pdvobj);
949         struct recv_priv        *precvpriv = &adapter->recvpriv;
950         struct usb_device       *pusbd = pdvobj->pusbdev;
951
952
953         if (RTW_CANNOT_RX(adapter) || (precvbuf == NULL)) {
954                 goto exit;
955         }
956
957         usb_init_recvbuf(adapter, precvbuf);
958
959         if (precvbuf->pskb == NULL) {
960                 SIZE_PTR tmpaddr = 0;
961                 SIZE_PTR alignment = 0;
962
963                 precvbuf->pskb = skb_dequeue(&precvpriv->free_recv_skb_queue);
964                 if (NULL != precvbuf->pskb)
965                         goto recv_buf_hook;
966
967                 #ifndef CONFIG_FIX_NR_BULKIN_BUFFER
968                 precvbuf->pskb = rtw_skb_alloc(MAX_RECVBUF_SZ + RECVBUFF_ALIGN_SZ);
969                 #endif
970
971                 if (precvbuf->pskb == NULL) {
972                         if (0)
973                                 RTW_INFO("usb_read_port() enqueue precvbuf=%p\n", precvbuf);
974                         /* enqueue precvbuf and wait for free skb */
975                         rtw_enqueue_recvbuf(precvbuf, &precvpriv->recv_buf_pending_queue);
976                         goto exit;
977                 }
978
979                 tmpaddr = (SIZE_PTR)precvbuf->pskb->data;
980                 alignment = tmpaddr & (RECVBUFF_ALIGN_SZ - 1);
981                 skb_reserve(precvbuf->pskb, (RECVBUFF_ALIGN_SZ - alignment));
982         }
983
984 recv_buf_hook:
985         precvbuf->phead = precvbuf->pskb->head;
986         precvbuf->pdata = precvbuf->pskb->data;
987         precvbuf->ptail = skb_tail_pointer(precvbuf->pskb);
988         precvbuf->pend = skb_end_pointer(precvbuf->pskb);
989         precvbuf->pbuf = precvbuf->pskb->data;
990
991         purb = precvbuf->purb;
992
993         /* translate DMA FIFO addr to pipehandle */
994         pipe = ffaddr2pipehdl(pdvobj, addr);
995
996         usb_fill_bulk_urb(purb, pusbd, pipe,
997                 precvbuf->pbuf,
998                 MAX_RECVBUF_SZ,
999                 usb_read_port_complete,
1000                 precvbuf);
1001
1002         err = usb_submit_urb(purb, GFP_ATOMIC);
1003         if (err && err != (-EPERM)) {
1004                 RTW_INFO("cannot submit rx in-token(err = 0x%08x),urb_status = %d\n"
1005                         , err, purb->status);
1006                 goto exit;
1007         }
1008
1009         ATOMIC_INC(&(precvpriv->rx_pending_cnt));
1010         ret = _SUCCESS;
1011
1012 exit:
1013
1014
1015         return ret;
1016 }
1017 #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
1018
1019 #ifdef CONFIG_USB_INTERRUPT_IN_PIPE
1020 void usb_read_interrupt_complete(struct urb *purb, struct pt_regs *regs)
1021 {
1022         int     err;
1023         _adapter        *padapter = (_adapter *)purb->context;
1024
1025         if (RTW_CANNOT_RX(padapter)) {
1026                 RTW_INFO("%s() RX Warning! bDriverStopped(%s) OR bSurpriseRemoved(%s)\n"
1027                         , __func__
1028                         , rtw_is_drv_stopped(padapter) ? "True" : "False"
1029                         , rtw_is_surprise_removed(padapter) ? "True" : "False");
1030
1031                 return;
1032         }
1033
1034         if (purb->status == 0) {/*SUCCESS*/
1035                 if (purb->actual_length > INTERRUPT_MSG_FORMAT_LEN)
1036                         RTW_INFO("usb_read_interrupt_complete: purb->actual_length > INTERRUPT_MSG_FORMAT_LEN(%d)\n", INTERRUPT_MSG_FORMAT_LEN);
1037
1038                 rtw_hal_interrupt_handler(padapter, purb->actual_length, purb->transfer_buffer);
1039
1040                 err = usb_submit_urb(purb, GFP_ATOMIC);
1041                 if ((err) && (err != (-EPERM)))
1042                         RTW_INFO("cannot submit interrupt in-token(err = 0x%08x),urb_status = %d\n", err, purb->status);
1043         } else {
1044                 RTW_INFO("###=> usb_read_interrupt_complete => urb status(%d)\n", purb->status);
1045
1046                 switch (purb->status) {
1047                 case -EINVAL:
1048                 case -EPIPE:
1049                 case -ENODEV:
1050                 case -ESHUTDOWN:
1051                 case -ENOENT:
1052                         rtw_set_drv_stopped(padapter);
1053                         break;
1054                 case -EPROTO:
1055                         break;
1056                 case -EINPROGRESS:
1057                         RTW_INFO("ERROR: URB IS IN PROGRESS!/n");
1058                         break;
1059                 default:
1060                         break;
1061                 }
1062         }
1063 }
1064
1065 u32 usb_read_interrupt(struct intf_hdl *pintfhdl, u32 addr)
1066 {
1067         int     err;
1068         unsigned int pipe;
1069         u32     ret = _SUCCESS;
1070         _adapter                        *adapter = pintfhdl->padapter;
1071         struct dvobj_priv       *pdvobj = adapter_to_dvobj(adapter);
1072         struct recv_priv        *precvpriv = &adapter->recvpriv;
1073         struct usb_device       *pusbd = pdvobj->pusbdev;
1074
1075
1076         if (RTW_CANNOT_RX(adapter)) {
1077                 return _FAIL;
1078         }
1079
1080         /*translate DMA FIFO addr to pipehandle*/
1081         pipe = ffaddr2pipehdl(pdvobj, addr);
1082
1083         usb_fill_int_urb(precvpriv->int_in_urb, pusbd, pipe,
1084                         precvpriv->int_in_buf,
1085                         INTERRUPT_MSG_FORMAT_LEN,
1086                         usb_read_interrupt_complete,
1087                         adapter,
1088                         1);
1089
1090         err = usb_submit_urb(precvpriv->int_in_urb, GFP_ATOMIC);
1091         if ((err) && (err != (-EPERM))) {
1092                 RTW_INFO("cannot submit interrupt in-token(err = 0x%08x), urb_status = %d\n", err, precvpriv->int_in_urb->status);
1093                 ret = _FAIL;
1094         }
1095
1096         return ret;
1097 }
1098 #endif /* CONFIG_USB_INTERRUPT_IN_PIPE */