2
*************************************************************************
4
* 5F., No.36, Taiyuan St., Jhubei City,
8
* (c) Copyright 2002-2007, Ralink Technology, Inc.
10
* This program is free software; you can redistribute it and/or modify *
11
* it under the terms of the GNU General Public License as published by *
12
* the Free Software Foundation; either version 2 of the License, or *
13
* (at your option) any later version. *
15
* This program is distributed in the hope that it will be useful, *
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18
* GNU General Public License for more details. *
20
* You should have received a copy of the GNU General Public License *
21
* along with this program; if not, write to the *
22
* Free Software Foundation, Inc., *
23
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25
*************************************************************************/
27
#include "rt_config.h"
29
/* Following information will be show when you run 'modinfo' */
30
/* If you have a solution for the bug in current version of driver, please e-mail me. */
31
/* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */
32
MODULE_AUTHOR("Paul Lin <paul_lin@ralinktech.com>");
33
MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver");
34
MODULE_LICENSE("GPL");
36
MODULE_VERSION(STA_DRIVER_VERSION);
40
struct usb_device_id rtusb_usb_id[] = {
42
{USB_DEVICE(0x148F, 0x2770)}, /* Ralink */
43
{USB_DEVICE(0x148F, 0x2870)}, /* Ralink */
44
{USB_DEVICE(0x07B8, 0x2870)}, /* AboCom */
45
{USB_DEVICE(0x07B8, 0x2770)}, /* AboCom */
46
{USB_DEVICE(0x0DF6, 0x0039)}, /* Sitecom 2770 */
47
{USB_DEVICE(0x0DF6, 0x003F)}, /* Sitecom 2770 */
48
{USB_DEVICE(0x083A, 0x7512)}, /* Arcadyan 2770 */
49
{USB_DEVICE(0x0789, 0x0162)}, /* Logitec 2870 */
50
{USB_DEVICE(0x0789, 0x0163)}, /* Logitec 2870 */
51
{USB_DEVICE(0x0789, 0x0164)}, /* Logitec 2870 */
52
{USB_DEVICE(0x177f, 0x0302)}, /* lsusb */
53
{USB_DEVICE(0x0B05, 0x1731)}, /* Asus */
54
{USB_DEVICE(0x0B05, 0x1732)}, /* Asus */
55
{USB_DEVICE(0x0B05, 0x1742)}, /* Asus */
56
{USB_DEVICE(0x0DF6, 0x0017)}, /* Sitecom */
57
{USB_DEVICE(0x0DF6, 0x002B)}, /* Sitecom */
58
{USB_DEVICE(0x0DF6, 0x002C)}, /* Sitecom */
59
{USB_DEVICE(0x0DF6, 0x002D)}, /* Sitecom */
60
{USB_DEVICE(0x14B2, 0x3C06)}, /* Conceptronic */
61
{USB_DEVICE(0x14B2, 0x3C28)}, /* Conceptronic */
62
{USB_DEVICE(0x2019, 0xED06)}, /* Planex Communications, Inc. */
63
{USB_DEVICE(0x07D1, 0x3C09)}, /* D-Link */
64
{USB_DEVICE(0x07D1, 0x3C11)}, /* D-Link */
65
{USB_DEVICE(0x14B2, 0x3C07)}, /* AL */
66
{USB_DEVICE(0x050D, 0x8053)}, /* Belkin */
67
{USB_DEVICE(0x050D, 0x825B)}, /* Belkin */
68
{USB_DEVICE(0x050D, 0x935A)}, /* Belkin F6D4050 v1 */
69
{USB_DEVICE(0x050D, 0x935B)}, /* Belkin F6D4050 v2 */
70
{USB_DEVICE(0x14B2, 0x3C23)}, /* Airlink */
71
{USB_DEVICE(0x14B2, 0x3C27)}, /* Airlink */
72
{USB_DEVICE(0x07AA, 0x002F)}, /* Corega */
73
{USB_DEVICE(0x07AA, 0x003C)}, /* Corega */
74
{USB_DEVICE(0x07AA, 0x003F)}, /* Corega */
75
{USB_DEVICE(0x1044, 0x800B)}, /* Gigabyte */
76
{USB_DEVICE(0x15A9, 0x0006)}, /* Sparklan */
77
{USB_DEVICE(0x083A, 0xB522)}, /* SMC */
78
{USB_DEVICE(0x083A, 0xA618)}, /* SMC */
79
{USB_DEVICE(0x083A, 0x8522)}, /* Arcadyan */
80
{USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */
81
{USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */
82
{USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */
83
{USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */
84
{USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */
85
{USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */
86
{USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */
87
{USB_DEVICE(0x0471, 0x200f)}, /* Philips */
88
{USB_DEVICE(0x14B2, 0x3C25)}, /* Draytek */
89
{USB_DEVICE(0x13D3, 0x3247)}, /* AzureWave */
90
{USB_DEVICE(0x083A, 0x6618)}, /* Accton */
91
{USB_DEVICE(0x15c5, 0x0008)}, /* Amit */
92
{USB_DEVICE(0x0E66, 0x0001)}, /* Hawking */
93
{USB_DEVICE(0x0E66, 0x0003)}, /* Hawking */
94
{USB_DEVICE(0x129B, 0x1828)}, /* Siemens */
95
{USB_DEVICE(0x157E, 0x300E)}, /* U-Media */
96
{USB_DEVICE(0x050d, 0x805c)},
97
{USB_DEVICE(0x050d, 0x815c)},
98
{USB_DEVICE(0x1482, 0x3C09)}, /* Abocom */
99
{USB_DEVICE(0x14B2, 0x3C09)}, /* Alpha */
100
{USB_DEVICE(0x04E8, 0x2018)}, /* samsung linkstick2 */
101
{USB_DEVICE(0x1690, 0x0740)}, /* Askey */
102
{USB_DEVICE(0x5A57, 0x0280)}, /* Zinwell */
103
{USB_DEVICE(0x5A57, 0x0282)}, /* Zinwell */
104
{USB_DEVICE(0x7392, 0x7718)},
105
{USB_DEVICE(0x7392, 0x7717)},
106
{USB_DEVICE(0x0411, 0x016f)}, /* MelCo.,Inc. WLI-UC-G301N */
107
{USB_DEVICE(0x1737, 0x0070)}, /* Linksys WUSB100 */
108
{USB_DEVICE(0x1737, 0x0071)}, /* Linksys WUSB600N */
109
{USB_DEVICE(0x1737, 0x0078)}, /* Linksys WUSB100v2 */
110
{USB_DEVICE(0x0411, 0x00e8)}, /* Buffalo WLI-UC-G300N */
111
{USB_DEVICE(0x050d, 0x815c)}, /* Belkin F5D8053 */
112
{USB_DEVICE(0x100D, 0x9031)}, /* Motorola 2770 */
113
#endif /* RT2870 // */
115
{USB_DEVICE(0x148F, 0x3070)}, /* Ralink 3070 */
116
{USB_DEVICE(0x148F, 0x3071)}, /* Ralink 3071 */
117
{USB_DEVICE(0x148F, 0x3072)}, /* Ralink 3072 */
118
{USB_DEVICE(0x0DB0, 0x3820)}, /* Ralink 3070 */
119
{USB_DEVICE(0x0DB0, 0x871C)}, /* Ralink 3070 */
120
{USB_DEVICE(0x0DB0, 0x822C)}, /* Ralink 3070 */
121
{USB_DEVICE(0x0DB0, 0x871B)}, /* Ralink 3070 */
122
{USB_DEVICE(0x0DB0, 0x822B)}, /* Ralink 3070 */
123
{USB_DEVICE(0x0DF6, 0x003E)}, /* Sitecom 3070 */
124
{USB_DEVICE(0x0DF6, 0x0042)}, /* Sitecom 3072 */
125
{USB_DEVICE(0x0DF6, 0x0048)}, /* Sitecom 3070 */
126
{USB_DEVICE(0x0DF6, 0x0047)}, /* Sitecom 3071 */
127
{USB_DEVICE(0x14B2, 0x3C12)}, /* AL 3070 */
128
{USB_DEVICE(0x18C5, 0x0012)}, /* Corega 3070 */
129
{USB_DEVICE(0x083A, 0x7511)}, /* Arcadyan 3070 */
130
{USB_DEVICE(0x083A, 0xA701)}, /* SMC 3070 */
131
{USB_DEVICE(0x083A, 0xA702)}, /* SMC 3072 */
132
{USB_DEVICE(0x1740, 0x9703)}, /* EnGenius 3070 */
133
{USB_DEVICE(0x1740, 0x9705)}, /* EnGenius 3071 */
134
{USB_DEVICE(0x1740, 0x9706)}, /* EnGenius 3072 */
135
{USB_DEVICE(0x1740, 0x9707)}, /* EnGenius 3070 */
136
{USB_DEVICE(0x1740, 0x9708)}, /* EnGenius 3071 */
137
{USB_DEVICE(0x1740, 0x9709)}, /* EnGenius 3072 */
138
{USB_DEVICE(0x13D3, 0x3273)}, /* AzureWave 3070 */
139
{USB_DEVICE(0x13D3, 0x3305)}, /* AzureWave 3070*/
140
{USB_DEVICE(0x1044, 0x800D)}, /* Gigabyte GN-WB32L 3070 */
141
{USB_DEVICE(0x2019, 0xAB25)}, /* Planex Communications, Inc. RT3070 */
142
{USB_DEVICE(0x07B8, 0x3070)}, /* AboCom 3070 */
143
{USB_DEVICE(0x07B8, 0x3071)}, /* AboCom 3071 */
144
{USB_DEVICE(0x07B8, 0x3072)}, /* Abocom 3072 */
145
{USB_DEVICE(0x7392, 0x7711)}, /* Edimax 3070 */
146
{USB_DEVICE(0x1A32, 0x0304)}, /* Quanta 3070 */
147
{USB_DEVICE(0x1EDA, 0x2310)}, /* AirTies 3070 */
148
{USB_DEVICE(0x07D1, 0x3C0A)}, /* D-Link 3072 */
149
{USB_DEVICE(0x07D1, 0x3C0D)}, /* D-Link 3070 */
150
{USB_DEVICE(0x07D1, 0x3C0E)}, /* D-Link 3070 */
151
{USB_DEVICE(0x07D1, 0x3C0F)}, /* D-Link 3070 */
152
{USB_DEVICE(0x07D1, 0x3C16)}, /* D-Link 3070 */
153
{USB_DEVICE(0x07D1, 0x3C17)}, /* D-Link 8070 */
154
{USB_DEVICE(0x1D4D, 0x000C)}, /* Pegatron Corporation 3070 */
155
{USB_DEVICE(0x1D4D, 0x000E)}, /* Pegatron Corporation 3070 */
156
{USB_DEVICE(0x5A57, 0x5257)}, /* Zinwell 3070 */
157
{USB_DEVICE(0x5A57, 0x0283)}, /* Zinwell 3072 */
158
{USB_DEVICE(0x04BB, 0x0945)}, /* I-O DATA 3072 */
159
{USB_DEVICE(0x04BB, 0x0947)}, /* I-O DATA 3070 */
160
{USB_DEVICE(0x04BB, 0x0948)}, /* I-O DATA 3072 */
161
{USB_DEVICE(0x203D, 0x1480)}, /* Encore 3070 */
162
{USB_DEVICE(0x20B8, 0x8888)}, /* PARA INDUSTRIAL 3070 */
163
{USB_DEVICE(0x0B05, 0x1784)}, /* Asus 3072 */
164
{USB_DEVICE(0x203D, 0x14A9)}, /* Encore 3070*/
165
{USB_DEVICE(0x0DB0, 0x899A)}, /* MSI 3070*/
166
{USB_DEVICE(0x0DB0, 0x3870)}, /* MSI 3070*/
167
{USB_DEVICE(0x0DB0, 0x870A)}, /* MSI 3070*/
168
{USB_DEVICE(0x0DB0, 0x6899)}, /* MSI 3070 */
169
{USB_DEVICE(0x0DB0, 0x3822)}, /* MSI 3070 */
170
{USB_DEVICE(0x0DB0, 0x3871)}, /* MSI 3070 */
171
{USB_DEVICE(0x0DB0, 0x871A)}, /* MSI 3070 */
172
{USB_DEVICE(0x0DB0, 0x822A)}, /* MSI 3070 */
173
{USB_DEVICE(0x0DB0, 0x3821)}, /* Ralink 3070 */
174
{USB_DEVICE(0x0DB0, 0x821A)}, /* Ralink 3070 */
175
{USB_DEVICE(0x083A, 0xA703)}, /* IO-MAGIC */
176
{USB_DEVICE(0x13D3, 0x3307)}, /* Azurewave */
177
{USB_DEVICE(0x13D3, 0x3321)}, /* Azurewave */
178
{USB_DEVICE(0x07FA, 0x7712)}, /* Edimax */
179
{USB_DEVICE(0x0789, 0x0166)}, /* Edimax */
180
{USB_DEVICE(0x148F, 0x2070)}, /* Edimax */
181
#endif /* RT3070 // */
182
{USB_DEVICE(0x1737, 0x0077)}, /* Linksys WUSB54GC-EU v3 */
183
{USB_DEVICE(0x2001, 0x3C09)}, /* D-Link */
184
{USB_DEVICE(0x2001, 0x3C0A)}, /* D-Link 3072 */
185
{USB_DEVICE(0x2019, 0xED14)}, /* Planex Communications, Inc. */
186
{USB_DEVICE(0x0411, 0x015D)}, /* Buffalo Airstation WLI-UC-GN */
187
{} /* Terminating entry */
190
int const rtusb_usb_id_len =
191
sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
193
MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
195
static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd);
197
static int __devinit rt2870_probe(IN struct usb_interface *intf,
198
IN struct usb_device *usb_dev,
199
IN const struct usb_device_id *dev_id,
200
struct rt_rtmp_adapter **ppAd);
203
#define PF_NOFREEZE 0
206
extern int rt28xx_close(IN struct net_device *net_dev);
207
extern int rt28xx_open(struct net_device *net_dev);
209
static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
210
IN struct usb_interface *intf,
211
struct rt_rtmp_adapter *pAd);
214
========================================================================
216
Check the chipset vendor/product ID.
219
_dev_p Point to the PCI or USB device
226
========================================================================
228
BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
230
struct usb_interface *intf = (struct usb_interface *)_dev_p;
231
struct usb_device *dev_p = interface_to_usbdev(intf);
234
for (i = 0; i < rtusb_usb_id_len; i++) {
235
if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
236
dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) {
237
printk(KERN_INFO "rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
238
dev_p->descriptor.idVendor,
239
dev_p->descriptor.idProduct);
244
if (i == rtusb_usb_id_len) {
245
printk(KERN_ERR "rt2870: Error! Device Descriptor not matching!\n");
252
/**************************************************************************/
253
/**************************************************************************/
254
/*tested for kernel 2.6series */
255
/**************************************************************************/
256
/**************************************************************************/
259
static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
260
static int rt2870_resume(struct usb_interface *intf);
261
#endif /* CONFIG_PM // */
263
static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
264
IN struct usb_interface *intf,
265
struct rt_rtmp_adapter *pAd)
267
struct usb_host_interface *iface_desc;
268
unsigned long BulkOutIdx;
271
/* get the active interface descriptor */
272
iface_desc = intf->cur_altsetting;
274
/* get # of enpoints */
275
pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
276
DBGPRINT(RT_DEBUG_TRACE,
277
("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
279
/* Configure Pipes */
282
for (i = 0; i < pAd->NumberOfPipes; i++) {
283
if ((iface_desc->endpoint[i].desc.bmAttributes ==
284
USB_ENDPOINT_XFER_BULK) &&
285
((iface_desc->endpoint[i].desc.bEndpointAddress &
286
USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) {
288
iface_desc->endpoint[i].desc.bEndpointAddress;
289
pAd->BulkInMaxPacketSize =
290
le2cpu16(iface_desc->endpoint[i].desc.
293
DBGPRINT_RAW(RT_DEBUG_TRACE,
294
("BULK IN MaxPacketSize = %d\n",
295
pAd->BulkInMaxPacketSize));
296
DBGPRINT_RAW(RT_DEBUG_TRACE,
297
("EP address = 0x%2x\n",
298
iface_desc->endpoint[i].desc.
301
if ((iface_desc->endpoint[i].desc.bmAttributes ==
302
USB_ENDPOINT_XFER_BULK)
304
((iface_desc->endpoint[i].desc.
305
bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
307
/* there are 6 bulk out EP. EP6 highest priority. */
308
/* EP1-4 is EDCA. EP5 is HCCA. */
309
pAd->BulkOutEpAddr[BulkOutIdx++] =
310
iface_desc->endpoint[i].desc.bEndpointAddress;
311
pAd->BulkOutMaxPacketSize =
312
le2cpu16(iface_desc->endpoint[i].desc.
315
DBGPRINT_RAW(RT_DEBUG_TRACE,
316
("BULK OUT MaxPacketSize = %d\n",
317
pAd->BulkOutMaxPacketSize));
318
DBGPRINT_RAW(RT_DEBUG_TRACE,
319
("EP address = 0x%2x \n",
320
iface_desc->endpoint[i].desc.
325
if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) {
327
(KERN_ERR "%s: Could not find both bulk-in and bulk-out endpoints\n",
332
pAd->config = &dev->config->desc;
333
usb_set_intfdata(intf, pAd);
339
static int __devinit rtusb_probe(struct usb_interface *intf,
340
const struct usb_device_id *id)
342
struct rt_rtmp_adapter *pAd;
343
struct usb_device *dev;
346
dev = interface_to_usbdev(intf);
347
dev = usb_get_dev(dev);
349
rv = rt2870_probe(intf, dev, id, &pAd);
356
static void rtusb_disconnect(struct usb_interface *intf)
358
struct usb_device *dev = interface_to_usbdev(intf);
359
struct rt_rtmp_adapter *pAd;
361
pAd = usb_get_intfdata(intf);
362
usb_set_intfdata(intf, NULL);
364
rt2870_disconnect(dev, pAd);
367
struct usb_driver rtusb_driver = {
369
.probe = rtusb_probe,
370
.disconnect = rtusb_disconnect,
371
.id_table = rtusb_usb_id,
374
suspend:rt2870_suspend,
375
resume:rt2870_resume,
381
void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd)
383
/* clear PS packets */
384
/* clear TxSw packets */
387
static int rt2870_suspend(struct usb_interface *intf, pm_message_t state)
389
struct net_device *net_dev;
390
struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
392
DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
393
net_dev = pAd->net_dev;
394
netif_device_detach(net_dev);
396
pAd->PM_FlgSuspend = 1;
397
if (netif_running(net_dev)) {
398
RTUSBCancelPendingBulkInIRP(pAd);
399
RTUSBCancelPendingBulkOutIRP(pAd);
401
DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
405
static int rt2870_resume(struct usb_interface *intf)
407
struct net_device *net_dev;
408
struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
410
DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
412
pAd->PM_FlgSuspend = 0;
413
net_dev = pAd->net_dev;
414
netif_device_attach(net_dev);
415
netif_start_queue(net_dev);
416
netif_carrier_on(net_dev);
417
netif_wake_queue(net_dev);
419
DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
422
#endif /* CONFIG_PM // */
424
/* Init driver module */
425
int __init rtusb_init(void)
427
printk(KERN_DEBUG "rtusb init --->\n");
428
return usb_register(&rtusb_driver);
431
/* Deinit driver module */
432
void __exit rtusb_exit(void)
434
usb_deregister(&rtusb_driver);
435
printk(KERN_DEBUG "<--- rtusb exit\n");
438
module_init(rtusb_init);
439
module_exit(rtusb_exit);
441
/*--------------------------------------------------------------------- */
442
/* function declarations */
443
/*--------------------------------------------------------------------- */
446
========================================================================
451
*Context the pAd, driver control block pointer
457
========================================================================
459
int MlmeThread(IN void *Context)
461
struct rt_rtmp_adapter *pAd;
462
struct rt_rtmp_os_task *pTask;
469
RtmpOSTaskCustomize(pTask);
471
while (!pTask->task_killed) {
472
#ifdef KTHREAD_SUPPORT
473
RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
475
RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
477
/* unlock the device pointers */
479
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
484
/* lock the device pointers , need to check if required */
485
/*down(&(pAd->usbdev_semaphore)); */
487
if (!pAd->PM_FlgSuspend)
491
/* notify the exit routine that we're actually exiting now
493
* complete()/wait_for_completion() is similar to up()/down(),
494
* except that complete() is safe in the case where the structure
495
* is getting deleted in a parallel mode of execution (i.e. just
496
* after the down() -- that's necessary for the thread-shutdown
499
* complete_and_exit() goes even further than this -- it is safe in
500
* the case that the thread of the caller is going away (not just
501
* the structure) -- this is necessary for the module-remove case.
502
* This is important in preemption kernels, which transfer the flow
503
* of execution immediately upon a complete().
505
DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__));
506
#ifndef KTHREAD_SUPPORT
507
pTask->taskPID = THREAD_PID_INIT_VALUE;
508
complete_and_exit(&pTask->taskComplete, 0);
515
========================================================================
517
USB command kernel thread.
520
*Context the pAd, driver control block pointer
526
========================================================================
528
int RTUSBCmdThread(IN void *Context)
530
struct rt_rtmp_adapter *pAd;
531
struct rt_rtmp_os_task *pTask;
538
RtmpOSTaskCustomize(pTask);
540
NdisAcquireSpinLock(&pAd->CmdQLock);
541
pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
542
NdisReleaseSpinLock(&pAd->CmdQLock);
544
while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) {
545
#ifdef KTHREAD_SUPPORT
546
RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
548
/* lock the device pointers */
549
RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
552
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
557
if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
560
if (!pAd->PM_FlgSuspend)
564
if (pAd && !pAd->PM_FlgSuspend) { /* Clear the CmdQElements. */
565
struct rt_cmdqelmt *pCmdQElmt = NULL;
567
NdisAcquireSpinLock(&pAd->CmdQLock);
568
pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
569
while (pAd->CmdQ.size) {
570
RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
572
if (pCmdQElmt->CmdFromNdis == TRUE) {
573
if (pCmdQElmt->buffer != NULL)
576
os_free_mem(pAd, (u8 *)pCmdQElmt);
578
if ((pCmdQElmt->buffer != NULL)
579
&& (pCmdQElmt->bufferlength != 0))
582
os_free_mem(pAd, (u8 *)pCmdQElmt);
587
NdisReleaseSpinLock(&pAd->CmdQLock);
589
/* notify the exit routine that we're actually exiting now
591
* complete()/wait_for_completion() is similar to up()/down(),
592
* except that complete() is safe in the case where the structure
593
* is getting deleted in a parallel mode of execution (i.e. just
594
* after the down() -- that's necessary for the thread-shutdown
597
* complete_and_exit() goes even further than this -- it is safe in
598
* the case that the thread of the caller is going away (not just
599
* the structure) -- this is necessary for the module-remove case.
600
* This is important in preemption kernels, which transfer the flow
601
* of execution immediately upon a complete().
603
DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n"));
605
#ifndef KTHREAD_SUPPORT
606
pTask->taskPID = THREAD_PID_INIT_VALUE;
607
complete_and_exit(&pTask->taskComplete, 0);
613
void RTUSBWatchDog(struct rt_rtmp_adapter *pAd)
615
struct rt_ht_tx_context *pHTTXContext;
617
unsigned long irqFlags;
619
BOOLEAN needDumpSeq = FALSE;
624
RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
625
if ((MACValue & 0xff) != 0) {
626
DBGPRINT(RT_DEBUG_TRACE,
627
("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n",
629
RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
630
while ((MACValue & 0xff) != 0 && (idx++ < 10)) {
631
RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
634
RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
637
if (pAd->watchDogRxOverFlowCnt >= 2) {
638
DBGPRINT(RT_DEBUG_TRACE,
639
("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
642
(fRTMP_ADAPTER_RESET_IN_PROGRESS |
643
fRTMP_ADAPTER_BULKIN_RESET |
644
fRTMP_ADAPTER_HALT_IN_PROGRESS |
645
fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
646
DBGPRINT(RT_DEBUG_TRACE,
647
("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
648
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
649
RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
653
pAd->watchDogRxOverFlowCnt = 0;
656
RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt);
658
for (idx = 0; idx < NUM_OF_TX_RING; idx++) {
661
RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
662
if ((pAd->BulkOutPending[idx] == TRUE)
663
&& pAd->watchDogTxPendingCnt) {
664
int actual_length = 0, transfer_buffer_length = 0;
665
BOOLEAN isDataPacket = FALSE;
666
pAd->watchDogTxPendingCnt[idx]++;
668
if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
671
(fRTMP_ADAPTER_RESET_IN_PROGRESS |
672
fRTMP_ADAPTER_HALT_IN_PROGRESS |
673
fRTMP_ADAPTER_NIC_NOT_EXIST |
674
fRTMP_ADAPTER_BULKOUT_RESET)))
676
/* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */
678
(struct rt_ht_tx_context *)(&pAd->TxContext[idx]);
679
if (pHTTXContext->IRPPending) { /* Check TxContext. */
680
pUrb = pHTTXContext->pUrb;
682
actual_length = pUrb->actual_length;
683
transfer_buffer_length =
684
pUrb->transfer_buffer_length;
686
} else if (idx == MGMTPIPEIDX) {
687
struct rt_tx_context *pMLMEContext, *pNULLContext,
690
/*Check MgmtContext. */
692
(struct rt_tx_context *)(pAd->MgmtRing.
697
(struct rt_tx_context *)(&pAd->PsPollContext);
699
(struct rt_tx_context *)(&pAd->NullContext);
701
if (pMLMEContext->IRPPending) {
702
ASSERT(pMLMEContext->
704
pUrb = pMLMEContext->pUrb;
705
} else if (pNULLContext->IRPPending) {
706
ASSERT(pNULLContext->
708
pUrb = pNULLContext->pUrb;
709
} else if (pPsPollContext->IRPPending) {
710
ASSERT(pPsPollContext->
712
pUrb = pPsPollContext->pUrb;
716
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
719
printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n",
720
idx, pAd->watchDogTxPendingCnt[idx],
721
pAd->TransferedLength[idx],
722
actual_length, transfer_buffer_length);
726
&& pAd->TransferedLength[idx] ==
728
&& pAd->TransferedLength[idx] <
729
transfer_buffer_length
730
&& actual_length != 0
731
/* && TxRxQ_Pcnt==0 */
732
&& pAd->watchDogTxPendingCnt[idx] >
734
|| isDataPacket == FALSE
735
|| pAd->watchDogTxPendingCnt[idx] >
737
DBGPRINT(RT_DEBUG_TRACE,
738
("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n",
740
DBGPRINT(RT_DEBUG_TRACE,
741
("Unlink the pending URB!\n"));
743
RTUSB_UNLINK_URB(pUrb);
744
/* Sleep 200 microseconds to give cancellation time to work */
745
/*RTMPusecDelay(200); */
749
DBGPRINT(RT_DEBUG_ERROR,
750
("Unknown bulkOut URB maybe hanged!\n"));
753
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
757
if (isDataPacket == TRUE)
758
pAd->TransferedLength[idx] = actual_length;
760
RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
764
/* For Sigma debug, dump the ba_reordering sequence. */
765
if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) {
767
struct rt_ba_rec_entry *pBAEntry = NULL;
769
struct reordering_mpdu *mpdu_blk;
771
Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
773
pBAEntry = &pAd->BATable.BARecEntry[Idx];
774
if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) {
775
DBGPRINT(RT_DEBUG_TRACE,
776
("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
777
NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
778
mpdu_blk = pBAEntry->list.next;
780
DBGPRINT(RT_DEBUG_TRACE,
781
("\t%d:Seq-%d, bAMSDU-%d!\n", count,
784
mpdu_blk = mpdu_blk->next;
788
DBGPRINT(RT_DEBUG_TRACE,
789
("\npBAEntry->LastIndSeq=%d!\n",
790
pBAEntry->LastIndSeq));
791
NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
797
========================================================================
799
Release allocated resources.
802
*dev Point to the PCI or USB device
803
pAd driver control block pointer
809
========================================================================
811
static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd)
813
DBGPRINT(RT_DEBUG_ERROR,
814
("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
815
dev->bus->bus_name, dev->devpath));
818
printk(KERN_ERR "rtusb_disconnect: pAd == NULL!\n");
821
RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
823
/* for debug, wait to show some messages to /proc system */
826
RtmpPhyNetDevExit(pAd, pAd->net_dev);
828
/* FIXME: Shall we need following delay and flush the schedule?? */
830
flush_scheduled_work();
833
/* free the root net_device */
834
RtmpOSNetDevFree(pAd->net_dev);
836
RtmpRaDevCtrlExit(pAd);
838
/* release a use of the usb device structure */
842
DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
845
static int __devinit rt2870_probe(IN struct usb_interface *intf,
846
IN struct usb_device *usb_dev,
847
IN const struct usb_device_id *dev_id,
848
struct rt_rtmp_adapter **ppAd)
850
struct net_device *net_dev = NULL;
851
struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
854
struct rt_rtmp_os_netdev_op_hook netDevHook;
856
DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n"));
858
/* Check chipset vendor/product ID */
859
/*if (RT28XXChipsetCheck(_dev_p) == FALSE) */
862
/*RtmpDevInit============================================= */
863
/* Allocate struct rt_rtmp_adapter adapter structure */
864
handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
865
if (handle == NULL) {
867
("rt2870_probe(): Allocate memory for os handle failed!\n");
870
((struct os_cookie *)handle)->pUsb_Dev = usb_dev;
872
rv = RTMPAllocAdapterBlock(handle, &pAd);
873
if (rv != NDIS_STATUS_SUCCESS) {
877
/*USBDevInit============================================== */
878
if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE)
879
goto err_out_free_radev;
881
RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB);
883
/*NetDevInit============================================== */
884
net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
886
goto err_out_free_radev;
888
/* Here are the net_device structure with usb specific parameters.
889
* for supporting Network Manager.
890
* Set the sysfs physical device reference for the network logical device if set prior to registration will
891
* cause a symlink during initialization.
893
SET_NETDEV_DEV(net_dev, &(usb_dev->dev));
895
pAd->StaCfg.OriDevType = net_dev->type;
897
/*All done, it's time to register the net device to linux kernel. */
898
/* Register this device */
899
status = RtmpOSNetDevAttach(net_dev, &netDevHook);
901
goto err_out_free_netdev;
903
#ifdef KTHREAD_SUPPORT
904
init_waitqueue_head(&pAd->mlmeTask.kthread_q);
905
init_waitqueue_head(&pAd->timerTask.kthread_q);
906
init_waitqueue_head(&pAd->cmdQTask.kthread_q);
911
DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n"));
915
/* --------------------------- ERROR HANDLE --------------------------- */
917
RtmpOSNetDevFree(net_dev);
920
RTMPFreeAdapter(pAd);