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