Staging: rt2870sta: Add more device IDs from vendor drivers
[pandora-kernel.git] / drivers / staging / rt2860 / usb_main_dev.c
1 /*
2  *************************************************************************
3  * Ralink Tech Inc.
4  * 5F., No.36, Taiyuan St., Jhubei City,
5  * Hsinchu County 302,
6  * Taiwan, R.O.C.
7  *
8  * (c) Copyright 2002-2007, Ralink Technology, Inc.
9  *
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.                                   *
14  *                                                                       *
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.                          *
19  *                                                                       *
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.             *
24  *                                                                       *
25  *************************************************************************/
26
27 #include "rt_config.h"
28
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 mail to me. */
31 /* Otherwise post to forum in 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");
35 #ifdef MODULE_VERSION
36 MODULE_VERSION(STA_DRIVER_VERSION);
37 #endif
38
39 /* module table */
40 struct usb_device_id rtusb_usb_id[] = {
41 #ifdef RT2870
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, 0x935B)},   /* Belkin F6D4050 v2 */
69         {USB_DEVICE(0x14B2, 0x3C23)},   /* Airlink */
70         {USB_DEVICE(0x14B2, 0x3C27)},   /* Airlink */
71         {USB_DEVICE(0x07AA, 0x002F)},   /* Corega */
72         {USB_DEVICE(0x07AA, 0x003C)},   /* Corega */
73         {USB_DEVICE(0x07AA, 0x003F)},   /* Corega */
74         {USB_DEVICE(0x1044, 0x800B)},   /* Gigabyte */
75         {USB_DEVICE(0x15A9, 0x0006)},   /* Sparklan */
76         {USB_DEVICE(0x083A, 0xB522)},   /* SMC */
77         {USB_DEVICE(0x083A, 0xA618)},   /* SMC */
78         {USB_DEVICE(0x083A, 0x8522)},   /* Arcadyan */
79         {USB_DEVICE(0x083A, 0x7522)},   /* Arcadyan */
80         {USB_DEVICE(0x0CDE, 0x0022)},   /* ZCOM */
81         {USB_DEVICE(0x0586, 0x3416)},   /* Zyxel */
82         {USB_DEVICE(0x0586, 0x341a)},   /* Zyxel NWD-270N */
83         {USB_DEVICE(0x0CDE, 0x0025)},   /* Zyxel */
84         {USB_DEVICE(0x1740, 0x9701)},   /* EnGenius */
85         {USB_DEVICE(0x1740, 0x9702)},   /* EnGenius */
86         {USB_DEVICE(0x0471, 0x200f)},   /* Philips */
87         {USB_DEVICE(0x14B2, 0x3C25)},   /* Draytek */
88         {USB_DEVICE(0x13D3, 0x3247)},   /* AzureWave */
89         {USB_DEVICE(0x083A, 0x6618)},   /* Accton */
90         {USB_DEVICE(0x15c5, 0x0008)},   /* Amit */
91         {USB_DEVICE(0x0E66, 0x0001)},   /* Hawking */
92         {USB_DEVICE(0x0E66, 0x0003)},   /* Hawking */
93         {USB_DEVICE(0x129B, 0x1828)},   /* Siemens */
94         {USB_DEVICE(0x157E, 0x300E)},   /* U-Media */
95         {USB_DEVICE(0x050d, 0x805c)},
96         {USB_DEVICE(0x050d, 0x815c)},
97         {USB_DEVICE(0x1482, 0x3C09)},   /* Abocom */
98         {USB_DEVICE(0x14B2, 0x3C09)},   /* Alpha */
99         {USB_DEVICE(0x04E8, 0x2018)},   /* samsung linkstick2 */
100         {USB_DEVICE(0x1690, 0x0740)},   /* Askey */
101         {USB_DEVICE(0x5A57, 0x0280)},   /* Zinwell */
102         {USB_DEVICE(0x5A57, 0x0282)},   /* Zinwell */
103         {USB_DEVICE(0x7392, 0x7718)},
104         {USB_DEVICE(0x7392, 0x7717)},
105         {USB_DEVICE(0x0411, 0x016f)},   /* MelCo.,Inc. WLI-UC-G301N */
106         {USB_DEVICE(0x1737, 0x0070)},   /* Linksys WUSB100 */
107         {USB_DEVICE(0x1737, 0x0071)},   /* Linksys WUSB600N */
108         {USB_DEVICE(0x0411, 0x00e8)},   /* Buffalo WLI-UC-G300N */
109         {USB_DEVICE(0x050d, 0x815c)},   /* Belkin F5D8053 */
110         {USB_DEVICE(0x100D, 0x9031)},   /* Motorola 2770 */
111 #endif /* RT2870 // */
112 #ifdef RT3070
113         {USB_DEVICE(0x148F, 0x3070)},   /* Ralink 3070 */
114         {USB_DEVICE(0x148F, 0x3071)},   /* Ralink 3071 */
115         {USB_DEVICE(0x148F, 0x3072)},   /* Ralink 3072 */
116         {USB_DEVICE(0x0DB0, 0x3820)},   /* Ralink 3070 */
117         {USB_DEVICE(0x0DB0, 0x871C)},   /* Ralink 3070 */
118         {USB_DEVICE(0x0DB0, 0x822C)},   /* Ralink 3070 */
119         {USB_DEVICE(0x0DB0, 0x871B)},   /* Ralink 3070 */
120         {USB_DEVICE(0x0DB0, 0x822B)},   /* Ralink 3070 */
121         {USB_DEVICE(0x0DF6, 0x003E)},   /* Sitecom 3070 */
122         {USB_DEVICE(0x0DF6, 0x0042)},   /* Sitecom 3072 */
123         {USB_DEVICE(0x0DF6, 0x0048)},   /* Sitecom 3070 */
124         {USB_DEVICE(0x0DF6, 0x0047)},   /* Sitecom 3071 */
125         {USB_DEVICE(0x14B2, 0x3C12)},   /* AL 3070 */
126         {USB_DEVICE(0x18C5, 0x0012)},   /* Corega 3070 */
127         {USB_DEVICE(0x083A, 0x7511)},   /* Arcadyan 3070 */
128         {USB_DEVICE(0x083A, 0xA701)},   /* SMC 3070 */
129         {USB_DEVICE(0x083A, 0xA702)},   /* SMC 3072 */
130         {USB_DEVICE(0x1740, 0x9703)},   /* EnGenius 3070 */
131         {USB_DEVICE(0x1740, 0x9705)},   /* EnGenius 3071 */
132         {USB_DEVICE(0x1740, 0x9706)},   /* EnGenius 3072 */
133         {USB_DEVICE(0x1740, 0x9707)},   /* EnGenius 3070 */
134         {USB_DEVICE(0x1740, 0x9708)},   /* EnGenius 3071 */
135         {USB_DEVICE(0x1740, 0x9709)},   /* EnGenius 3072 */
136         {USB_DEVICE(0x13D3, 0x3273)},   /* AzureWave 3070 */
137         {USB_DEVICE(0x13D3, 0x3305)},   /* AzureWave 3070*/
138         {USB_DEVICE(0x1044, 0x800D)},   /* Gigabyte GN-WB32L 3070 */
139         {USB_DEVICE(0x2019, 0xAB25)},   /* Planex Communications, Inc. RT3070 */
140         {USB_DEVICE(0x07B8, 0x3070)},   /* AboCom 3070 */
141         {USB_DEVICE(0x07B8, 0x3071)},   /* AboCom 3071 */
142         {USB_DEVICE(0x07B8, 0x3072)},   /* Abocom 3072 */
143         {USB_DEVICE(0x7392, 0x7711)},   /* Edimax 3070 */
144         {USB_DEVICE(0x1A32, 0x0304)},   /* Quanta 3070 */
145         {USB_DEVICE(0x1EDA, 0x2310)},   /* AirTies 3070 */
146         {USB_DEVICE(0x07D1, 0x3C0A)},   /* D-Link 3072 */
147         {USB_DEVICE(0x07D1, 0x3C0D)},   /* D-Link 3070 */
148         {USB_DEVICE(0x07D1, 0x3C0E)},   /* D-Link 3070 */
149         {USB_DEVICE(0x07D1, 0x3C0F)},   /* D-Link 3070 */
150         {USB_DEVICE(0x07D1, 0x3C16)},   /* D-Link 3070 */
151         {USB_DEVICE(0x07D1, 0x3C17)},   /* D-Link 8070 */
152         {USB_DEVICE(0x1D4D, 0x000C)},   /* Pegatron Corporation 3070 */
153         {USB_DEVICE(0x1D4D, 0x000E)},   /* Pegatron Corporation 3070 */
154         {USB_DEVICE(0x5A57, 0x5257)},   /* Zinwell 3070 */
155         {USB_DEVICE(0x5A57, 0x0283)},   /* Zinwell 3072 */
156         {USB_DEVICE(0x04BB, 0x0945)},   /* I-O DATA 3072 */
157         {USB_DEVICE(0x04BB, 0x0947)},   /* I-O DATA 3070 */
158         {USB_DEVICE(0x04BB, 0x0948)},   /* I-O DATA 3072 */
159         {USB_DEVICE(0x203D, 0x1480)},   /* Encore 3070 */
160         {USB_DEVICE(0x20B8, 0x8888)},   /* PARA INDUSTRIAL 3070 */
161         {USB_DEVICE(0x0B05, 0x1784)},   /* Asus 3072 */
162         {USB_DEVICE(0x203D, 0x14A9)},   /* Encore 3070*/
163         {USB_DEVICE(0x0DB0, 0x899A)},   /* MSI 3070*/
164         {USB_DEVICE(0x0DB0, 0x3870)},   /* MSI 3070*/
165         {USB_DEVICE(0x0DB0, 0x870A)},   /* MSI 3070*/
166         {USB_DEVICE(0x0DB0, 0x6899)},   /* MSI 3070 */
167         {USB_DEVICE(0x0DB0, 0x3822)},   /* MSI 3070 */
168         {USB_DEVICE(0x0DB0, 0x3871)},   /* MSI 3070 */
169         {USB_DEVICE(0x0DB0, 0x871A)},   /* MSI 3070 */
170         {USB_DEVICE(0x0DB0, 0x822A)},   /* MSI 3070 */
171         {USB_DEVICE(0x0DB0, 0x3821)},   /* Ralink 3070 */
172         {USB_DEVICE(0x0DB0, 0x821A)},   /* Ralink 3070 */
173         {USB_DEVICE(0x083A, 0xA703)},   /* IO-MAGIC */
174         {USB_DEVICE(0x13D3, 0x3307)},   /* Azurewave */
175         {USB_DEVICE(0x13D3, 0x3321)},   /* Azurewave */
176         {USB_DEVICE(0x07FA, 0x7712)},   /* Edimax */
177         {USB_DEVICE(0x0789, 0x0166)},   /* Edimax */
178         {USB_DEVICE(0x148F, 0x2070)},   /* Edimax */
179 #endif /* RT3070 // */
180         {USB_DEVICE(0x1737, 0x0077)},   /* Linksys WUSB54GC-EU v3 */
181         {USB_DEVICE(0x2001, 0x3C09)},   /* D-Link */
182         {USB_DEVICE(0x2001, 0x3C0A)},   /* D-Link 3072 */
183         {USB_DEVICE(0x2019, 0xED14)},   /* Planex Communications, Inc. */
184         {}                      /* Terminating entry */
185 };
186
187 int const rtusb_usb_id_len =
188     sizeof(rtusb_usb_id) / sizeof(struct usb_device_id);
189
190 MODULE_DEVICE_TABLE(usb, rtusb_usb_id);
191
192 static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd);
193
194 static int __devinit rt2870_probe(IN struct usb_interface *intf,
195                                   IN struct usb_device *usb_dev,
196                                   IN const struct usb_device_id *dev_id,
197                                   struct rt_rtmp_adapter **ppAd);
198
199 #ifndef PF_NOFREEZE
200 #define PF_NOFREEZE  0
201 #endif
202
203 extern int rt28xx_close(IN struct net_device *net_dev);
204 extern int rt28xx_open(struct net_device *net_dev);
205
206 static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
207                                 IN struct usb_interface *intf,
208                                 struct rt_rtmp_adapter *pAd);
209
210 /*
211 ========================================================================
212 Routine Description:
213     Check the chipset vendor/product ID.
214
215 Arguments:
216     _dev_p                              Point to the PCI or USB device
217
218 Return Value:
219     TRUE                                Check ok
220         FALSE                           Check fail
221
222 Note:
223 ========================================================================
224 */
225 BOOLEAN RT28XXChipsetCheck(IN void *_dev_p)
226 {
227         struct usb_interface *intf = (struct usb_interface *)_dev_p;
228         struct usb_device *dev_p = interface_to_usbdev(intf);
229         u32 i;
230
231         for (i = 0; i < rtusb_usb_id_len; i++) {
232                 if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor &&
233                     dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) {
234                         printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n",
235                                dev_p->descriptor.idVendor,
236                                dev_p->descriptor.idProduct);
237                         break;
238                 }
239         }
240
241         if (i == rtusb_usb_id_len) {
242                 printk("rt2870: Error! Device Descriptor not matching!\n");
243                 return FALSE;
244         }
245
246         return TRUE;
247 }
248
249 /**************************************************************************/
250 /**************************************************************************/
251 /*tested for kernel 2.6series */
252 /**************************************************************************/
253 /**************************************************************************/
254
255 #ifdef CONFIG_PM
256 static int rt2870_suspend(struct usb_interface *intf, pm_message_t state);
257 static int rt2870_resume(struct usb_interface *intf);
258 #endif /* CONFIG_PM // */
259
260 static BOOLEAN USBDevConfigInit(IN struct usb_device *dev,
261                                 IN struct usb_interface *intf,
262                                 struct rt_rtmp_adapter *pAd)
263 {
264         struct usb_host_interface *iface_desc;
265         unsigned long BulkOutIdx;
266         u32 i;
267
268         /* get the active interface descriptor */
269         iface_desc = intf->cur_altsetting;
270
271         /* get # of enpoints  */
272         pAd->NumberOfPipes = iface_desc->desc.bNumEndpoints;
273         DBGPRINT(RT_DEBUG_TRACE,
274                  ("NumEndpoints=%d\n", iface_desc->desc.bNumEndpoints));
275
276         /* Configure Pipes */
277         BulkOutIdx = 0;
278
279         for (i = 0; i < pAd->NumberOfPipes; i++) {
280                 if ((iface_desc->endpoint[i].desc.bmAttributes ==
281                      USB_ENDPOINT_XFER_BULK) &&
282                     ((iface_desc->endpoint[i].desc.bEndpointAddress &
283                       USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)) {
284                         pAd->BulkInEpAddr =
285                             iface_desc->endpoint[i].desc.bEndpointAddress;
286                         pAd->BulkInMaxPacketSize =
287                             le2cpu16(iface_desc->endpoint[i].desc.
288                                      wMaxPacketSize);
289
290                         DBGPRINT_RAW(RT_DEBUG_TRACE,
291                                      ("BULK IN MaxPacketSize = %d\n",
292                                       pAd->BulkInMaxPacketSize));
293                         DBGPRINT_RAW(RT_DEBUG_TRACE,
294                                      ("EP address = 0x%2x\n",
295                                       iface_desc->endpoint[i].desc.
296                                       bEndpointAddress));
297                 } else
298                     if ((iface_desc->endpoint[i].desc.bmAttributes ==
299                          USB_ENDPOINT_XFER_BULK)
300                         &&
301                         ((iface_desc->endpoint[i].desc.
302                           bEndpointAddress & USB_ENDPOINT_DIR_MASK) ==
303                          USB_DIR_OUT)) {
304                         /* there are 6 bulk out EP. EP6 highest priority. */
305                         /* EP1-4 is EDCA.  EP5 is HCCA. */
306                         pAd->BulkOutEpAddr[BulkOutIdx++] =
307                             iface_desc->endpoint[i].desc.bEndpointAddress;
308                         pAd->BulkOutMaxPacketSize =
309                             le2cpu16(iface_desc->endpoint[i].desc.
310                                      wMaxPacketSize);
311
312                         DBGPRINT_RAW(RT_DEBUG_TRACE,
313                                      ("BULK OUT MaxPacketSize = %d\n",
314                                       pAd->BulkOutMaxPacketSize));
315                         DBGPRINT_RAW(RT_DEBUG_TRACE,
316                                      ("EP address = 0x%2x  \n",
317                                       iface_desc->endpoint[i].desc.
318                                       bEndpointAddress));
319                 }
320         }
321
322         if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) {
323                 printk
324                     ("%s: Could not find both bulk-in and bulk-out endpoints\n",
325                      __FUNCTION__);
326                 return FALSE;
327         }
328
329         pAd->config = &dev->config->desc;
330         usb_set_intfdata(intf, pAd);
331
332         return TRUE;
333
334 }
335
336 static int __devinit rtusb_probe(struct usb_interface *intf,
337                        const struct usb_device_id *id)
338 {
339         struct rt_rtmp_adapter *pAd;
340         struct usb_device *dev;
341         int rv;
342
343         dev = interface_to_usbdev(intf);
344         dev = usb_get_dev(dev);
345
346         rv = rt2870_probe(intf, dev, id, &pAd);
347         if (rv != 0)
348                 usb_put_dev(dev);
349
350         return rv;
351 }
352
353 static void rtusb_disconnect(struct usb_interface *intf)
354 {
355         struct usb_device *dev = interface_to_usbdev(intf);
356         struct rt_rtmp_adapter *pAd;
357
358         pAd = usb_get_intfdata(intf);
359         usb_set_intfdata(intf, NULL);
360
361         rt2870_disconnect(dev, pAd);
362 }
363
364 struct usb_driver rtusb_driver = {
365         .name = "rt2870",
366         .probe = rtusb_probe,
367         .disconnect = rtusb_disconnect,
368         .id_table = rtusb_usb_id,
369
370 #ifdef CONFIG_PM
371 suspend:rt2870_suspend,
372 resume:rt2870_resume,
373 #endif
374 };
375
376 #ifdef CONFIG_PM
377
378 void RT2870RejectPendingPackets(struct rt_rtmp_adapter *pAd)
379 {
380         /* clear PS packets */
381         /* clear TxSw packets */
382 }
383
384 static int rt2870_suspend(struct usb_interface *intf, pm_message_t state)
385 {
386         struct net_device *net_dev;
387         struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
388
389         DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_suspend()\n"));
390         net_dev = pAd->net_dev;
391         netif_device_detach(net_dev);
392
393         pAd->PM_FlgSuspend = 1;
394         if (netif_running(net_dev)) {
395                 RTUSBCancelPendingBulkInIRP(pAd);
396                 RTUSBCancelPendingBulkOutIRP(pAd);
397         }
398         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_suspend()\n"));
399         return 0;
400 }
401
402 static int rt2870_resume(struct usb_interface *intf)
403 {
404         struct net_device *net_dev;
405         struct rt_rtmp_adapter *pAd = usb_get_intfdata(intf);
406
407         DBGPRINT(RT_DEBUG_TRACE, ("===> rt2870_resume()\n"));
408
409         pAd->PM_FlgSuspend = 0;
410         net_dev = pAd->net_dev;
411         netif_device_attach(net_dev);
412         netif_start_queue(net_dev);
413         netif_carrier_on(net_dev);
414         netif_wake_queue(net_dev);
415
416         DBGPRINT(RT_DEBUG_TRACE, ("<=== rt2870_resume()\n"));
417         return 0;
418 }
419 #endif /* CONFIG_PM // */
420
421 /* Init driver module */
422 int __init rtusb_init(void)
423 {
424         printk("rtusb init --->\n");
425         return usb_register(&rtusb_driver);
426 }
427
428 /* Deinit driver module */
429 void __exit rtusb_exit(void)
430 {
431         usb_deregister(&rtusb_driver);
432         printk("<--- rtusb exit\n");
433 }
434
435 module_init(rtusb_init);
436 module_exit(rtusb_exit);
437
438 /*--------------------------------------------------------------------- */
439 /* function declarations                                                                                                */
440 /*--------------------------------------------------------------------- */
441
442 /*
443 ========================================================================
444 Routine Description:
445     MLME kernel thread.
446
447 Arguments:
448         *Context                        the pAd, driver control block pointer
449
450 Return Value:
451     0                                   close the thread
452
453 Note:
454 ========================================================================
455 */
456 int MlmeThread(IN void *Context)
457 {
458         struct rt_rtmp_adapter *pAd;
459         struct rt_rtmp_os_task *pTask;
460         int status;
461         status = 0;
462
463         pTask = Context;
464         pAd = pTask->priv;
465
466         RtmpOSTaskCustomize(pTask);
467
468         while (!pTask->task_killed) {
469 #ifdef KTHREAD_SUPPORT
470                 RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
471 #else
472                 RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
473
474                 /* unlock the device pointers */
475                 if (status != 0) {
476                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
477                         break;
478                 }
479 #endif
480
481                 /* lock the device pointers , need to check if required */
482                 /*down(&(pAd->usbdev_semaphore)); */
483
484                 if (!pAd->PM_FlgSuspend)
485                         MlmeHandler(pAd);
486         }
487
488         /* notify the exit routine that we're actually exiting now
489          *
490          * complete()/wait_for_completion() is similar to up()/down(),
491          * except that complete() is safe in the case where the structure
492          * is getting deleted in a parallel mode of execution (i.e. just
493          * after the down() -- that's necessary for the thread-shutdown
494          * case.
495          *
496          * complete_and_exit() goes even further than this -- it is safe in
497          * the case that the thread of the caller is going away (not just
498          * the structure) -- this is necessary for the module-remove case.
499          * This is important in preemption kernels, which transfer the flow
500          * of execution immediately upon a complete().
501          */
502         DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __FUNCTION__));
503 #ifndef KTHREAD_SUPPORT
504         pTask->taskPID = THREAD_PID_INIT_VALUE;
505         complete_and_exit(&pTask->taskComplete, 0);
506 #endif
507         return 0;
508
509 }
510
511 /*
512 ========================================================================
513 Routine Description:
514     USB command kernel thread.
515
516 Arguments:
517         *Context                        the pAd, driver control block pointer
518
519 Return Value:
520     0                                   close the thread
521
522 Note:
523 ========================================================================
524 */
525 int RTUSBCmdThread(IN void *Context)
526 {
527         struct rt_rtmp_adapter *pAd;
528         struct rt_rtmp_os_task *pTask;
529         int status;
530         status = 0;
531
532         pTask = Context;
533         pAd = pTask->priv;
534
535         RtmpOSTaskCustomize(pTask);
536
537         NdisAcquireSpinLock(&pAd->CmdQLock);
538         pAd->CmdQ.CmdQState = RTMP_TASK_STAT_RUNNING;
539         NdisReleaseSpinLock(&pAd->CmdQLock);
540
541         while (pAd && pAd->CmdQ.CmdQState == RTMP_TASK_STAT_RUNNING) {
542 #ifdef KTHREAD_SUPPORT
543                 RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
544 #else
545                 /* lock the device pointers */
546                 RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
547
548                 if (status != 0) {
549                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
550                         break;
551                 }
552 #endif
553
554                 if (pAd->CmdQ.CmdQState == RTMP_TASK_STAT_STOPED)
555                         break;
556
557                 if (!pAd->PM_FlgSuspend)
558                         CMDHandler(pAd);
559         }
560
561         if (pAd && !pAd->PM_FlgSuspend) {       /* Clear the CmdQElements. */
562                 struct rt_cmdqelmt *pCmdQElmt = NULL;
563
564                 NdisAcquireSpinLock(&pAd->CmdQLock);
565                 pAd->CmdQ.CmdQState = RTMP_TASK_STAT_STOPED;
566                 while (pAd->CmdQ.size) {
567                         RTUSBDequeueCmd(&pAd->CmdQ, &pCmdQElmt);
568                         if (pCmdQElmt) {
569                                 if (pCmdQElmt->CmdFromNdis == TRUE) {
570                                         if (pCmdQElmt->buffer != NULL)
571                                                 os_free_mem(pAd,
572                                                             pCmdQElmt->buffer);
573                                         os_free_mem(pAd, (u8 *)pCmdQElmt);
574                                 } else {
575                                         if ((pCmdQElmt->buffer != NULL)
576                                             && (pCmdQElmt->bufferlength != 0))
577                                                 os_free_mem(pAd,
578                                                             pCmdQElmt->buffer);
579                                         os_free_mem(pAd, (u8 *)pCmdQElmt);
580                                 }
581                         }
582                 }
583
584                 NdisReleaseSpinLock(&pAd->CmdQLock);
585         }
586         /* notify the exit routine that we're actually exiting now
587          *
588          * complete()/wait_for_completion() is similar to up()/down(),
589          * except that complete() is safe in the case where the structure
590          * is getting deleted in a parallel mode of execution (i.e. just
591          * after the down() -- that's necessary for the thread-shutdown
592          * case.
593          *
594          * complete_and_exit() goes even further than this -- it is safe in
595          * the case that the thread of the caller is going away (not just
596          * the structure) -- this is necessary for the module-remove case.
597          * This is important in preemption kernels, which transfer the flow
598          * of execution immediately upon a complete().
599          */
600         DBGPRINT(RT_DEBUG_TRACE, ("<---RTUSBCmdThread\n"));
601
602 #ifndef KTHREAD_SUPPORT
603         pTask->taskPID = THREAD_PID_INIT_VALUE;
604         complete_and_exit(&pTask->taskComplete, 0);
605 #endif
606         return 0;
607
608 }
609
610 void RTUSBWatchDog(struct rt_rtmp_adapter *pAd)
611 {
612         struct rt_ht_tx_context *pHTTXContext;
613         int idx;
614         unsigned long irqFlags;
615         PURB pUrb;
616         BOOLEAN needDumpSeq = FALSE;
617         u32 MACValue;
618         u32 TxRxQ_Pcnt;
619
620         idx = 0;
621         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
622         if ((MACValue & 0xff) != 0) {
623                 DBGPRINT(RT_DEBUG_TRACE,
624                          ("TX QUEUE 0 Not EMPTY(Value=0x%0x)!\n",
625                           MACValue));
626                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40012);
627                 while ((MACValue & 0xff) != 0 && (idx++ < 10)) {
628                         RTMP_IO_READ32(pAd, TXRXQ_PCNT, &MACValue);
629                         RTMPusecDelay(1);
630                 }
631                 RTMP_IO_WRITE32(pAd, PBF_CFG, 0xf40006);
632         }
633
634         if (pAd->watchDogRxOverFlowCnt >= 2) {
635                 DBGPRINT(RT_DEBUG_TRACE,
636                          ("Maybe the Rx Bulk-In hanged! Cancel the pending Rx bulks request!\n"));
637                 if ((!RTMP_TEST_FLAG
638                      (pAd,
639                       (fRTMP_ADAPTER_RESET_IN_PROGRESS |
640                        fRTMP_ADAPTER_BULKIN_RESET |
641                        fRTMP_ADAPTER_HALT_IN_PROGRESS |
642                        fRTMP_ADAPTER_NIC_NOT_EXIST)))) {
643                         DBGPRINT(RT_DEBUG_TRACE,
644                                  ("Call CMDTHREAD_RESET_BULK_IN to cancel the pending Rx Bulk!\n"));
645                         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_BULKIN_RESET);
646                         RTUSBEnqueueInternalCmd(pAd, CMDTHREAD_RESET_BULK_IN,
647                                                 NULL, 0);
648                         needDumpSeq = TRUE;
649                 }
650                 pAd->watchDogRxOverFlowCnt = 0;
651         }
652
653         RTUSBReadMACRegister(pAd, 0x438, &TxRxQ_Pcnt);
654
655         for (idx = 0; idx < NUM_OF_TX_RING; idx++) {
656                 pUrb = NULL;
657
658                 RTMP_IRQ_LOCK(&pAd->BulkOutLock[idx], irqFlags);
659                 if ((pAd->BulkOutPending[idx] == TRUE)
660                     && pAd->watchDogTxPendingCnt) {
661                         int actual_length = 0, transfer_buffer_length = 0;
662                         BOOLEAN isDataPacket = FALSE;
663                         pAd->watchDogTxPendingCnt[idx]++;
664
665                         if ((pAd->watchDogTxPendingCnt[idx] > 2) &&
666                             (!RTMP_TEST_FLAG
667                              (pAd,
668                               (fRTMP_ADAPTER_RESET_IN_PROGRESS |
669                                fRTMP_ADAPTER_HALT_IN_PROGRESS |
670                                fRTMP_ADAPTER_NIC_NOT_EXIST |
671                                fRTMP_ADAPTER_BULKOUT_RESET)))
672                             ) {
673                                 /* FIXME: Following code just support single bulk out. If you wanna support multiple bulk out. Modify it! */
674                                 pHTTXContext =
675                                     (struct rt_ht_tx_context *)(&pAd->TxContext[idx]);
676                                 if (pHTTXContext->IRPPending) { /* Check TxContext. */
677                                         pUrb = pHTTXContext->pUrb;
678
679                                         actual_length = pUrb->actual_length;
680                                         transfer_buffer_length =
681                                             pUrb->transfer_buffer_length;
682                                         isDataPacket = TRUE;
683                                 } else if (idx == MGMTPIPEIDX) {
684                                         struct rt_tx_context *pMLMEContext, *pNULLContext,
685                                             *pPsPollContext;
686
687                                         /*Check MgmtContext. */
688                                         pMLMEContext =
689                                             (struct rt_tx_context *)(pAd->MgmtRing.
690                                                            Cell[pAd->MgmtRing.
691                                                                 TxDmaIdx].
692                                                            AllocVa);
693                                         pPsPollContext =
694                                             (struct rt_tx_context *)(&pAd->PsPollContext);
695                                         pNULLContext =
696                                             (struct rt_tx_context *)(&pAd->NullContext);
697
698                                         if (pMLMEContext->IRPPending) {
699                                                 ASSERT(pMLMEContext->
700                                                        IRPPending);
701                                                 pUrb = pMLMEContext->pUrb;
702                                         } else if (pNULLContext->IRPPending) {
703                                                 ASSERT(pNULLContext->
704                                                        IRPPending);
705                                                 pUrb = pNULLContext->pUrb;
706                                         } else if (pPsPollContext->IRPPending) {
707                                                 ASSERT(pPsPollContext->
708                                                        IRPPending);
709                                                 pUrb = pPsPollContext->pUrb;
710                                         }
711                                 }
712
713                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
714                                                 irqFlags);
715
716                                 printk(KERN_INFO "%d:%lu LTL=%d , TL=%d L:%d\n",
717                                        idx, pAd->watchDogTxPendingCnt[idx],
718                                        pAd->TransferedLength[idx],
719                                        actual_length, transfer_buffer_length);
720
721                                 if (pUrb) {
722                                         if ((isDataPacket
723                                              && pAd->TransferedLength[idx] ==
724                                              actual_length
725                                              && pAd->TransferedLength[idx] <
726                                              transfer_buffer_length
727                                              && actual_length != 0
728 /*                                      && TxRxQ_Pcnt==0 */
729                                              && pAd->watchDogTxPendingCnt[idx] >
730                                              3)
731                                             || isDataPacket == FALSE
732                                             || pAd->watchDogTxPendingCnt[idx] >
733                                             6) {
734                                                 DBGPRINT(RT_DEBUG_TRACE,
735                                                          ("Maybe the Tx Bulk-Out hanged! Cancel the pending Tx bulks request of idx(%d)!\n",
736                                                           idx));
737                                                 DBGPRINT(RT_DEBUG_TRACE,
738                                                          ("Unlink the pending URB!\n"));
739                                                 /* unlink it now */
740                                                 RTUSB_UNLINK_URB(pUrb);
741                                                 /* Sleep 200 microseconds to give cancellation time to work */
742                                                 /*RTMPusecDelay(200); */
743                                                 needDumpSeq = TRUE;
744                                         }
745                                 } else {
746                                         DBGPRINT(RT_DEBUG_ERROR,
747                                                  ("Unknown bulkOut URB maybe hanged!\n"));
748                                 }
749                         } else {
750                                 RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx],
751                                                 irqFlags);
752                         }
753
754                         if (isDataPacket == TRUE)
755                                 pAd->TransferedLength[idx] = actual_length;
756                 } else {
757                         RTMP_IRQ_UNLOCK(&pAd->BulkOutLock[idx], irqFlags);
758                 }
759         }
760
761         /* For Sigma debug, dump the ba_reordering sequence. */
762         if ((needDumpSeq == TRUE) && (pAd->CommonCfg.bDisableReordering == 0)) {
763                 u16 Idx;
764                 struct rt_ba_rec_entry *pBAEntry = NULL;
765                 u8 count = 0;
766                 struct reordering_mpdu *mpdu_blk;
767
768                 Idx = pAd->MacTab.Content[BSSID_WCID].BARecWcidArray[0];
769
770                 pBAEntry = &pAd->BATable.BARecEntry[Idx];
771                 if ((pBAEntry->list.qlen > 0) && (pBAEntry->list.next != NULL)) {
772                         DBGPRINT(RT_DEBUG_TRACE,
773                                  ("NICUpdateRawCounters():The Queueing pkt in reordering buffer:\n"));
774                         NdisAcquireSpinLock(&pBAEntry->RxReRingLock);
775                         mpdu_blk = pBAEntry->list.next;
776                         while (mpdu_blk) {
777                                 DBGPRINT(RT_DEBUG_TRACE,
778                                          ("\t%d:Seq-%d, bAMSDU-%d!\n", count,
779                                           mpdu_blk->Sequence,
780                                           mpdu_blk->bAMSDU));
781                                 mpdu_blk = mpdu_blk->next;
782                                 count++;
783                         }
784
785                         DBGPRINT(RT_DEBUG_TRACE,
786                                  ("\npBAEntry->LastIndSeq=%d!\n",
787                                   pBAEntry->LastIndSeq));
788                         NdisReleaseSpinLock(&pBAEntry->RxReRingLock);
789                 }
790         }
791 }
792
793 /*
794 ========================================================================
795 Routine Description:
796     Release allocated resources.
797
798 Arguments:
799     *dev                                Point to the PCI or USB device
800         pAd                                     driver control block pointer
801
802 Return Value:
803     None
804
805 Note:
806 ========================================================================
807 */
808 static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pAd)
809 {
810         DBGPRINT(RT_DEBUG_ERROR,
811                  ("rtusb_disconnect: unregister usbnet usb-%s-%s\n",
812                   dev->bus->bus_name, dev->devpath));
813         if (!pAd) {
814                 usb_put_dev(dev);
815                 printk("rtusb_disconnect: pAd == NULL!\n");
816                 return;
817         }
818         RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST);
819
820         /* for debug, wait to show some messages to /proc system */
821         udelay(1);
822
823         RtmpPhyNetDevExit(pAd, pAd->net_dev);
824
825         /* FIXME: Shall we need following delay and flush the schedule?? */
826         udelay(1);
827         flush_scheduled_work();
828         udelay(1);
829
830         /* free the root net_device */
831         RtmpOSNetDevFree(pAd->net_dev);
832
833         RtmpRaDevCtrlExit(pAd);
834
835         /* release a use of the usb device structure */
836         usb_put_dev(dev);
837         udelay(1);
838
839         DBGPRINT(RT_DEBUG_ERROR, (" RTUSB disconnect successfully\n"));
840 }
841
842 static int __devinit rt2870_probe(IN struct usb_interface *intf,
843                                   IN struct usb_device *usb_dev,
844                                   IN const struct usb_device_id *dev_id,
845                                   struct rt_rtmp_adapter **ppAd)
846 {
847         struct net_device *net_dev = NULL;
848         struct rt_rtmp_adapter *pAd = (struct rt_rtmp_adapter *)NULL;
849         int status, rv;
850         void *handle;
851         struct rt_rtmp_os_netdev_op_hook netDevHook;
852
853         DBGPRINT(RT_DEBUG_TRACE, ("===>rt2870_probe()!\n"));
854
855         /* Check chipset vendor/product ID */
856         /*if (RT28XXChipsetCheck(_dev_p) == FALSE) */
857         /*      goto err_out; */
858
859 /*RtmpDevInit============================================= */
860         /* Allocate struct rt_rtmp_adapter adapter structure */
861         handle = kmalloc(sizeof(struct os_cookie), GFP_KERNEL);
862         if (handle == NULL) {
863                 printk
864                     ("rt2870_probe(): Allocate memory for os handle failed!\n");
865                 return -ENOMEM;
866         }
867         ((struct os_cookie *)handle)->pUsb_Dev = usb_dev;
868
869         rv = RTMPAllocAdapterBlock(handle, &pAd);
870         if (rv != NDIS_STATUS_SUCCESS) {
871                 kfree(handle);
872                 goto err_out;
873         }
874 /*USBDevInit============================================== */
875         if (USBDevConfigInit(usb_dev, intf, pAd) == FALSE)
876                 goto err_out_free_radev;
877
878         RtmpRaDevCtrlInit(pAd, RTMP_DEV_INF_USB);
879
880 /*NetDevInit============================================== */
881         net_dev = RtmpPhyNetDevInit(pAd, &netDevHook);
882         if (net_dev == NULL)
883                 goto err_out_free_radev;
884
885         /* Here are the net_device structure with usb specific parameters. */
886         /* for supporting Network Manager.
887          * Set the sysfs physical device reference for the network logical device if set prior to registration will
888          * cause a symlink during initialization.
889          */
890         SET_NETDEV_DEV(net_dev, &(usb_dev->dev));
891
892         pAd->StaCfg.OriDevType = net_dev->type;
893
894 /*All done, it's time to register the net device to linux kernel. */
895         /* Register this device */
896         status = RtmpOSNetDevAttach(net_dev, &netDevHook);
897         if (status != 0)
898                 goto err_out_free_netdev;
899
900 #ifdef KTHREAD_SUPPORT
901         init_waitqueue_head(&pAd->mlmeTask.kthread_q);
902         init_waitqueue_head(&pAd->timerTask.kthread_q);
903         init_waitqueue_head(&pAd->cmdQTask.kthread_q);
904 #endif
905
906         *ppAd = pAd;
907
908         DBGPRINT(RT_DEBUG_TRACE, ("<===rt2870_probe()!\n"));
909
910         return 0;
911
912         /* --------------------------- ERROR HANDLE --------------------------- */
913 err_out_free_netdev:
914         RtmpOSNetDevFree(net_dev);
915
916 err_out_free_radev:
917         RTMPFreeAdapter(pAd);
918
919 err_out:
920         *ppAd = NULL;
921
922         return -1;
923
924 }